mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-10-12 02:22:55 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aee2bee856 | ||
|
|
cfa7b3c3bd | ||
|
|
76b310cc43 | ||
|
|
9a6acd2054 | ||
|
|
387020ece8 | ||
|
|
732b9670d2 | ||
|
|
1159c9ccae | ||
|
|
cadbf170f0 | ||
|
|
fc486c8b34 | ||
|
|
cfe43e3f2b | ||
|
|
6395481aa4 | ||
|
|
2380ab1e86 | ||
|
|
dd32bfb0cc | ||
|
|
b7d90bbe03 | ||
|
|
86170e177c | ||
|
|
bce3abc829 | ||
|
|
8d6125f067 | ||
|
|
506e3f0871 | ||
|
|
6145944dc7 | ||
|
|
61186b979b | ||
|
|
4d4b9a1175 | ||
|
|
133e2c8c61 | ||
|
|
38c341076d | ||
|
|
40e4422bbd | ||
|
|
98ac1cf9c1 | ||
|
|
56721240fa | ||
|
|
c81414cf25 | ||
|
|
2e195a35dc | ||
|
|
89d25a16ce | ||
|
|
9bc466edac | ||
|
|
32b7f3040e | ||
|
|
f066e215e5 | ||
|
|
4e65ff4689 | ||
|
|
1e8bf1c78a | ||
|
|
657c6519ea | ||
|
|
970c7f6a76 | ||
|
|
105e314ec8 | ||
|
|
dd963a042d | ||
|
|
0df2592622 | ||
|
|
eeacab0f19 | ||
|
|
b3e454d0b1 | ||
|
|
99d0031d65 | ||
|
|
5916bc2d39 | ||
|
|
2159944de4 | ||
|
|
f87aa83e9b | ||
|
|
b902cca791 | ||
|
|
86467e196b | ||
|
|
30f137699d | ||
|
|
7741154383 | ||
|
|
a6262a3aa9 | ||
|
|
1f33b16e01 | ||
|
|
04396c97e2 | ||
|
|
b1cdbdae61 | ||
|
|
747951b80b | ||
|
|
1bef2f8fda | ||
|
|
b0ac442096 | ||
|
|
99a5fb243c | ||
|
|
b2a575482e | ||
|
|
365e08b710 | ||
|
|
af3b79ff8b | ||
|
|
3724a53466 | ||
|
|
01e83cb4a0 | ||
|
|
cd77cdd1e8 | ||
|
|
22c421a427 | ||
|
|
59fe89f076 | ||
|
|
160011bd87 | ||
|
|
36ee4d68c7 | ||
|
|
dfc5bc5d87 |
@@ -0,0 +1 @@
|
||||
custom: 'https://www.paypal.com/donate?hosted_button_id=A34GMDLKA2V7G'
|
||||
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.
@@ -485,6 +485,8 @@ llave
|
||||
chaveta
|
||||
tono
|
||||
cuna
|
||||
correo
|
||||
contrasenia
|
||||
|
||||
# german
|
||||
|
||||
|
||||
@@ -3223,6 +3223,10 @@ nuke_gallery_pictures_newpicture
|
||||
Books
|
||||
grupo
|
||||
facturas
|
||||
aclaraciones
|
||||
preguntas
|
||||
personas
|
||||
estadisticas
|
||||
|
||||
# site:cn
|
||||
|
||||
|
||||
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.
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.
Binary file not shown.
@@ -223,4 +223,12 @@
|
||||
<error regexp="-10048: Syntax error"/>
|
||||
<error regexp="rdmStmtPrepare\(.+?\) returned"/>
|
||||
</dbms>
|
||||
|
||||
<dbms value="Virtuoso">
|
||||
<error regexp="SQ074: Line \d+:"/>
|
||||
<error regexp="SR185: Undefined procedure"/>
|
||||
<error regexp="SQ200: No table "/>
|
||||
<error regexp="Virtuoso S0002 Error"/>
|
||||
<error regexp="\[(Virtuoso Driver|Virtuoso iODBC Driver)\]\[Virtuoso Server\]"/>
|
||||
</dbms>
|
||||
</root>
|
||||
|
||||
@@ -1665,4 +1665,55 @@
|
||||
<search_table/>
|
||||
<search_column/>
|
||||
</dbms>
|
||||
|
||||
<dbms value="Virtuoso">
|
||||
<cast query="CAST(%s AS NCHAR)"/>
|
||||
<length query="LENGTH(%s)"/>
|
||||
<isnull query="__MAX_NOTNULL(%s,' ')"/>
|
||||
<delimiter query="||"/>
|
||||
<limit query="TOP (%d,%d)"/>
|
||||
<limitregexp query="\s+TOP\s*\(([\d]+)\s*\,\s*([\d]+)\)" query2="\s+TOP\s+([\d]+)"/>
|
||||
<limitgroupstart query="1"/>
|
||||
<limitgroupstop query="2"/>
|
||||
<limitstring query=" TOP "/>
|
||||
<order query="ORDER BY %s ASC"/>
|
||||
<count query="COUNT(%s)"/>
|
||||
<comment query="-- -" query2="/*"/>
|
||||
<concatenate query="%s||%s"/>
|
||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||
<inference query="ASCII(SUBSTRING((%s),%d,1))>%d"/>
|
||||
<banner query="sys_stat('st_dbms_name')||' - '||sys_stat('st_dbms_ver')"/>
|
||||
<current_user query="USERNAME()"/>
|
||||
<current_db query="UPPER(USERNAME())"/>
|
||||
<hostname query="sys_stat('st_host_name')"/>
|
||||
<table_comment/>
|
||||
<column_comment/>
|
||||
<is_dba query="USERNAME()='dba'"/>
|
||||
<dbs>
|
||||
<inband query="SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA"/>
|
||||
<blind query="SELECT DISTINCT TOP (%d,1) schema_name FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY 1" count="SELECT COUNT(DISTINCT(schema_name)) FROM INFORMATION_SCHEMA.SCHEMATA"/>
|
||||
</dbs>
|
||||
<tables>
|
||||
<inband query="SELECT table_schema,table_name FROM INFORMATION_SCHEMA.TABLES" condition="table_schema"/>
|
||||
<blind query="SELECT TOP (%d,1) table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s' ORDER BY 1" count="SELECT COUNT(table_name) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s'"/>
|
||||
</tables>
|
||||
<columns>
|
||||
<inband query="SELECT column_name,data_type FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND table_schema='%s'" condition="column_name"/>
|
||||
<blind query="SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND table_schema='%s'" query2="SELECT data_type FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND column_name='%s' AND table_schema='%s'" count="SELECT COUNT(column_name) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND table_schema='%s'" condition="column_name"/>
|
||||
</columns>
|
||||
<dump_table>
|
||||
<inband query="SELECT %s FROM %s.%s ORDER BY %s"/>
|
||||
<blind query="SELECT TOP (%d,1) %s FROM %s.%s ORDER BY %s" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||
</dump_table>
|
||||
<users>
|
||||
<inband query="SELECT u_name FROM SYS_USERS WHERE U_IS_ROLE=0 ORDER BY 1"/>
|
||||
<blind query="SELECT TOP (%d,1) u_name FROM SYS_USERS WHERE U_IS_ROLE=0 ORDER BY 1" count="SELECT COUNT(DISTINCT(u_name)) FROM SYS_USERS"/>
|
||||
</users>
|
||||
<privileges/>
|
||||
<roles/>
|
||||
<statements/>
|
||||
<search_db/>
|
||||
<search_table/>
|
||||
<search_column/>
|
||||
</dbms>
|
||||
</root>
|
||||
|
||||
@@ -734,6 +734,9 @@ rmillet, <rmillet42(at)gmail.com>
|
||||
Rub3nCT, <rub3nct(at)gmail.com>
|
||||
* for reporting a minor bug
|
||||
|
||||
sapra, <amanistaken(at)gmail.com>
|
||||
* for helping out with Python multiprocessing library on MacOS
|
||||
|
||||
shiftzwei, <shiftzwei(at)gmail.com>
|
||||
* for reporting a couple of bugs
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[](https://travis-ci.org/sqlmapproject/sqlmap) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://badge.fury.io/py/sqlmap) [](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aissue+is%3Aclosed) [](https://twitter.com/sqlmap)
|
||||
|
||||
sqlmap 是一个开源的渗透测试工具,可以用来自动化的检测,利用SQL注入漏洞,获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的渗透测试的功能选项,包括获取数据库中存储的数据,访问操作系统文件甚至可以通过外带数据连接的方式执行操作系统命令。
|
||||
sqlmap 是一个开源的渗透测试工具,可以用来自动化的检测,利用SQL注入漏洞,获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的渗透测试的功能选项,包括获取数据库中存储的数据,访问操作系统文件甚至可以通过带外数据连接的方式执行操作系统命令。
|
||||
|
||||
演示截图
|
||||
----
|
||||
|
||||
@@ -21,7 +21,7 @@ if sys.version_info >= (3, 0):
|
||||
xrange = range
|
||||
ord = lambda _: _
|
||||
|
||||
KEY = b"cwRAopWDYixMeqs3"
|
||||
KEY = b"ENWsCymUeJcXqSbD"
|
||||
|
||||
def xor(message, key):
|
||||
return b"".join(struct.pack('B', ord(message[i]) ^ ord(key[i % len(key)])) for i in range(len(message)))
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -129,7 +129,6 @@ class ReqHandler(BaseHTTPRequestHandler):
|
||||
self.url, self.params = path, params
|
||||
|
||||
if self.url == '/':
|
||||
|
||||
if not any(_ in self.params for _ in ("id", "query")):
|
||||
self.send_response(OK)
|
||||
self.send_header("Content-type", "text/html; charset=%s" % UNICODE_ENCODING)
|
||||
@@ -140,10 +139,12 @@ class ReqHandler(BaseHTTPRequestHandler):
|
||||
code, output = OK, ""
|
||||
|
||||
try:
|
||||
|
||||
if self.params.get("echo", ""):
|
||||
output += "%s<br>" % self.params["echo"]
|
||||
|
||||
if self.params.get("reflect", ""):
|
||||
output += "%s<br>" % self.params.get("id")
|
||||
|
||||
with _lock:
|
||||
if "query" in self.params:
|
||||
_cursor.execute(self.params["query"])
|
||||
@@ -156,18 +157,22 @@ class ReqHandler(BaseHTTPRequestHandler):
|
||||
|
||||
output += "<b>SQL results:</b><br>\n"
|
||||
|
||||
if results:
|
||||
output += "<table border=\"1\">\n"
|
||||
|
||||
for row in results:
|
||||
output += "<tr>"
|
||||
for value in row:
|
||||
output += "<td>%s</td>" % value
|
||||
output += "</tr>\n"
|
||||
|
||||
output += "</table>\n"
|
||||
if self.params.get("code", ""):
|
||||
if not results:
|
||||
code = INTERNAL_SERVER_ERROR
|
||||
else:
|
||||
output += "no results found"
|
||||
if results:
|
||||
output += "<table border=\"1\">\n"
|
||||
|
||||
for row in results:
|
||||
output += "<tr>"
|
||||
for value in row:
|
||||
output += "<td>%s</td>" % value
|
||||
output += "</tr>\n"
|
||||
|
||||
output += "</table>\n"
|
||||
else:
|
||||
output += "no results found"
|
||||
|
||||
output += "</body></html>"
|
||||
except Exception as ex:
|
||||
@@ -194,7 +199,7 @@ class ReqHandler(BaseHTTPRequestHandler):
|
||||
self.do_REQUEST()
|
||||
|
||||
def do_PUT(self):
|
||||
self.do_REQUEST()
|
||||
self.do_POST()
|
||||
|
||||
def do_HEAD(self):
|
||||
self.do_REQUEST()
|
||||
|
||||
@@ -529,7 +529,7 @@ def checkSqlInjection(place, parameter, value):
|
||||
truePage, trueHeaders, trueCode = threadData.lastComparisonPage or "", threadData.lastComparisonHeaders, threadData.lastComparisonCode
|
||||
trueRawResponse = "%s%s" % (trueHeaders, truePage)
|
||||
|
||||
if trueResult and not(truePage == falsePage and not kb.nullConnection):
|
||||
if trueResult and not(truePage == falsePage and not any((kb.nullConnection, conf.code))):
|
||||
# Perform the test's False request
|
||||
falseResult = Request.queryPage(genCmpPayload(), place, raise404=False)
|
||||
|
||||
@@ -991,7 +991,7 @@ def checkSuhosinPatch(injection):
|
||||
Checks for existence of Suhosin-patch (and alike) protection mechanism(s)
|
||||
"""
|
||||
|
||||
if injection.place == PLACE.GET:
|
||||
if injection.place in (PLACE.GET, PLACE.URI):
|
||||
debugMsg = "checking for parameter length "
|
||||
debugMsg += "constraining mechanisms"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
@@ -37,6 +37,7 @@ from lib.core.settings import RAIMA_ALIASES
|
||||
from lib.core.settings import SQLITE_ALIASES
|
||||
from lib.core.settings import SYBASE_ALIASES
|
||||
from lib.core.settings import VERTICA_ALIASES
|
||||
from lib.core.settings import VIRTUOSO_ALIASES
|
||||
from lib.utils.sqlalchemy import SQLAlchemy
|
||||
|
||||
from plugins.dbms.access.connector import Connector as AccessConn
|
||||
@@ -91,6 +92,8 @@ from plugins.dbms.sybase.connector import Connector as SybaseConn
|
||||
from plugins.dbms.sybase import SybaseMap
|
||||
from plugins.dbms.vertica.connector import Connector as VerticaConn
|
||||
from plugins.dbms.vertica import VerticaMap
|
||||
from plugins.dbms.virtuoso.connector import Connector as VirtuosoConn
|
||||
from plugins.dbms.virtuoso import VirtuosoMap
|
||||
|
||||
def setHandler():
|
||||
"""
|
||||
@@ -125,6 +128,7 @@ def setHandler():
|
||||
(DBMS.EXTREMEDB, EXTREMEDB_ALIASES, ExtremeDBMap, ExtremeDBConn),
|
||||
(DBMS.FRONTBASE, FRONTBASE_ALIASES, FrontBaseMap, FrontBaseConn),
|
||||
(DBMS.RAIMA, RAIMA_ALIASES, RaimaMap, RaimaConn),
|
||||
(DBMS.VIRTUOSO, VIRTUOSO_ALIASES, VirtuosoMap, VirtuosoConn),
|
||||
]
|
||||
|
||||
_ = max(_ if (conf.get("dbms") or Backend.getIdentifiedDbms() or kb.heuristicExtendedDbms or "").lower() in _[1] else () for _ in items)
|
||||
|
||||
+3
-3
@@ -488,7 +488,7 @@ class Agent(object):
|
||||
if not (Backend.isDbms(DBMS.SQLITE) and not isDBMSVersionAtLeast('3')):
|
||||
nulledCastedField = rootQuery.cast.query % field
|
||||
|
||||
if re.search("COUNT\(", field) and Backend.getIdentifiedDbms() in (DBMS.RAIMA,):
|
||||
if re.search(r"COUNT\(", field) and Backend.getIdentifiedDbms() in (DBMS.RAIMA,):
|
||||
pass
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI):
|
||||
nulledCastedField = rootQuery.isnull.query % (nulledCastedField, nulledCastedField)
|
||||
@@ -699,7 +699,7 @@ class Agent(object):
|
||||
elif fieldsNoSelect:
|
||||
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
|
||||
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.ALTIBASE, DBMS.MIMERSQL, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA):
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.ALTIBASE, DBMS.MIMERSQL, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA, DBMS.VIRTUOSO):
|
||||
if fieldsExists:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
|
||||
concatenatedQuery += "||'%s'" % kb.chars.stop
|
||||
@@ -1021,7 +1021,7 @@ class Agent(object):
|
||||
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (1, num)
|
||||
limitedQuery += " %s" % limitStr
|
||||
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.FRONTBASE,):
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.FRONTBASE, DBMS.VIRTUOSO):
|
||||
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
|
||||
if query.startswith("SELECT "):
|
||||
limitedQuery = query.replace("SELECT ", "SELECT %s " % limitStr, 1)
|
||||
|
||||
+23
-22
@@ -1531,7 +1531,7 @@ def parseTargetDirect():
|
||||
remote = False
|
||||
|
||||
for dbms in SUPPORTED_DBMS:
|
||||
details = re.search(r"^(?P<dbms>%s)://(?P<credentials>(?P<user>.*?)\:(?P<pass>.*)\@)?(?P<remote>(?P<hostname>[\w.-]+?)\:(?P<port>[\d]+)\/)?(?P<db>[\w\d\ \:\.\_\-\/\\]+?)$" % dbms, conf.direct, re.I)
|
||||
details = re.search(r"^(?P<dbms>%s)://(?P<credentials>(?P<user>.*?)\:(?P<pass>.*)\@)?(?P<remote>(?P<hostname>[\w.-]+?)\:(?P<port>[\d]+)\/)?(?P<db>[\w\d\ \:\.\_\-\/\\]*)$" % dbms, conf.direct, re.I)
|
||||
|
||||
if details:
|
||||
conf.dbms = details.group("dbms")
|
||||
@@ -2882,33 +2882,31 @@ def urldecode(value, encoding=None, unsafe="%%?&=;+%s" % CUSTOM_INJECTION_MARK_C
|
||||
True
|
||||
>>> urldecode('AND%201%3E%282%2B3%29%23', convall=False) == 'AND 1>(2%2B3)#'
|
||||
True
|
||||
>>> urldecode(b'AND%201%3E%282%2B3%29%23', convall=False) == 'AND 1>(2%2B3)#'
|
||||
True
|
||||
"""
|
||||
|
||||
result = value
|
||||
|
||||
if value:
|
||||
try:
|
||||
# for cases like T%C3%BCrk%C3%A7e
|
||||
value = str(value)
|
||||
except ValueError:
|
||||
pass
|
||||
finally:
|
||||
if convall:
|
||||
result = _urllib.parse.unquote_plus(value) if spaceplus else _urllib.parse.unquote(value)
|
||||
else:
|
||||
result = value
|
||||
charset = set(string.printable) - set(unsafe)
|
||||
value = getUnicode(value)
|
||||
|
||||
def _(match):
|
||||
char = decodeHex(match.group(1), binary=False)
|
||||
return char if char in charset else match.group(0)
|
||||
if convall:
|
||||
result = _urllib.parse.unquote_plus(value) if spaceplus else _urllib.parse.unquote(value)
|
||||
else:
|
||||
result = value
|
||||
charset = set(string.printable) - set(unsafe)
|
||||
|
||||
if spaceplus:
|
||||
result = result.replace('+', ' ') # plus sign has a special meaning in URL encoded data (hence the usage of _urllib.parse.unquote_plus in convall case)
|
||||
def _(match):
|
||||
char = decodeHex(match.group(1), binary=False)
|
||||
return char if char in charset else match.group(0)
|
||||
|
||||
result = re.sub(r"%([0-9a-fA-F]{2})", _, result)
|
||||
if spaceplus:
|
||||
result = result.replace('+', ' ') # plus sign has a special meaning in URL encoded data (hence the usage of _urllib.parse.unquote_plus in convall case)
|
||||
|
||||
result = getUnicode(result, encoding or UNICODE_ENCODING)
|
||||
result = re.sub(r"%([0-9a-fA-F]{2})", _, result)
|
||||
|
||||
result = getUnicode(result, encoding or UNICODE_ENCODING)
|
||||
|
||||
return result
|
||||
|
||||
@@ -3026,6 +3024,8 @@ def getPublicTypeMembers(type_, onlyValues=False):
|
||||
|
||||
>>> [_ for _ in getPublicTypeMembers(OS, True)]
|
||||
['Linux', 'Windows']
|
||||
>>> [_ for _ in getPublicTypeMembers(PAYLOAD.TECHNIQUE, True)]
|
||||
[1, 2, 3, 4, 5, 6]
|
||||
"""
|
||||
|
||||
retVal = []
|
||||
@@ -4200,7 +4200,7 @@ def safeSQLIdentificatorNaming(name, isTable=False):
|
||||
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE): # Note: in SQLite double-quotes are treated as string if column/identifier is non-existent (e.g. SELECT "foobar" FROM users)
|
||||
retVal = "`%s`" % retVal
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA):
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA, DBMS.VIRTUOSO):
|
||||
retVal = "\"%s\"" % retVal
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
||||
retVal = "\"%s\"" % retVal.upper()
|
||||
@@ -4238,7 +4238,7 @@ def unsafeSQLIdentificatorNaming(name):
|
||||
if isinstance(name, six.string_types):
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE):
|
||||
retVal = name.replace("`", "")
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA):
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA, DBMS.VIRTUOSO):
|
||||
retVal = name.replace("\"", "")
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
||||
retVal = name.replace("\"", "").upper()
|
||||
@@ -5250,7 +5250,8 @@ def parseRequestFile(reqFile, checkParams=True):
|
||||
continue
|
||||
|
||||
if re.search(r"^[\n]*%s.*?\.(%s)\sHTTP\/" % (HTTPMETHOD.GET, "|".join(CRAWL_EXCLUDE_EXTENSIONS)), request, re.I | re.M):
|
||||
continue
|
||||
if not re.search(r"^[\n]*%s[^\n]*\*[^\n]*\sHTTP\/" % HTTPMETHOD.GET, request, re.I | re.M):
|
||||
continue
|
||||
|
||||
getPostReq = False
|
||||
url = None
|
||||
|
||||
@@ -25,6 +25,8 @@ def cachedmethod(f):
|
||||
>>> __ = cachedmethod(lambda _: _)
|
||||
>>> __(1)
|
||||
1
|
||||
>>> __(1)
|
||||
1
|
||||
>>> __ = cachedmethod(lambda *args, **kwargs: args[0])
|
||||
>>> __(2)
|
||||
2
|
||||
|
||||
+7
-3
@@ -37,6 +37,7 @@ from lib.core.settings import RAIMA_ALIASES
|
||||
from lib.core.settings import SQLITE_ALIASES
|
||||
from lib.core.settings import SYBASE_ALIASES
|
||||
from lib.core.settings import VERTICA_ALIASES
|
||||
from lib.core.settings import VIRTUOSO_ALIASES
|
||||
|
||||
FIREBIRD_TYPES = {
|
||||
261: "BLOB",
|
||||
@@ -222,9 +223,9 @@ DUMP_REPLACEMENTS = {" ": NULL, "": BLANK}
|
||||
DBMS_DICT = {
|
||||
DBMS.MSSQL: (MSSQL_ALIASES, "python-pymssql", "https://github.com/pymssql/pymssql", "mssql+pymssql"),
|
||||
DBMS.MYSQL: (MYSQL_ALIASES, "python-pymysql", "https://github.com/PyMySQL/PyMySQL", "mysql"),
|
||||
DBMS.PGSQL: (PGSQL_ALIASES, "python-psycopg2", "http://initd.org/psycopg/", "postgresql"),
|
||||
DBMS.PGSQL: (PGSQL_ALIASES, "python-psycopg2", "https://github.com/psycopg/psycopg2", "postgresql"),
|
||||
DBMS.ORACLE: (ORACLE_ALIASES, "python cx_Oracle", "https://oracle.github.io/python-cx_Oracle/", "oracle"),
|
||||
DBMS.SQLITE: (SQLITE_ALIASES, "python-sqlite", "https://docs.python.org/2/library/sqlite3.html", "sqlite"),
|
||||
DBMS.SQLITE: (SQLITE_ALIASES, "python-sqlite", "https://docs.python.org/3/library/sqlite3.html", "sqlite"),
|
||||
DBMS.ACCESS: (ACCESS_ALIASES, "python-pyodbc", "https://github.com/mkleehammer/pyodbc", "access"),
|
||||
DBMS.FIREBIRD: (FIREBIRD_ALIASES, "python-kinterbasdb", "http://kinterbasdb.sourceforge.net/", "firebird"),
|
||||
DBMS.MAXDB: (MAXDB_ALIASES, None, None, "maxdb"),
|
||||
@@ -246,6 +247,7 @@ DBMS_DICT = {
|
||||
DBMS.EXTREMEDB: (EXTREMEDB_ALIASES, None, None, None),
|
||||
DBMS.FRONTBASE: (FRONTBASE_ALIASES, None, None, None),
|
||||
DBMS.RAIMA: (RAIMA_ALIASES, None, None, None),
|
||||
DBMS.VIRTUOSO: (VIRTUOSO_ALIASES, None, None, None),
|
||||
}
|
||||
|
||||
# Reference: https://blog.jooq.org/tag/sysibm-sysdummy1/
|
||||
@@ -283,6 +285,7 @@ HEURISTIC_NULL_EVAL = {
|
||||
DBMS.CACHE: "%SQLUPPER NULL",
|
||||
DBMS.EXTREMEDB: "NULLIFZERO(hashcode(NULL))",
|
||||
DBMS.RAIMA: "IF(ROWNUMBER()>0,CONVERT(NULL,TINYINT),NULL))",
|
||||
DBMS.VIRTUOSO: "__MAX_NOTNULL(NULL)",
|
||||
}
|
||||
|
||||
SQL_STATEMENTS = {
|
||||
@@ -363,6 +366,7 @@ OBSOLETE_OPTIONS = {
|
||||
"--ignore-401": "use '--ignore-code' instead",
|
||||
"--second-order": "use '--second-url' instead",
|
||||
"--purge-output": "use '--purge' instead",
|
||||
"--sqlmap-shell": "use '--shell' instead",
|
||||
"--check-payload": None,
|
||||
"--check-waf": None,
|
||||
"--pickled-options": "use '--api -c ...' instead",
|
||||
@@ -379,7 +383,7 @@ DUMP_DATA_PREPROCESS = {
|
||||
|
||||
DEFAULT_DOC_ROOTS = {
|
||||
OS.WINDOWS: ("C:/xampp/htdocs/", "C:/wamp/www/", "C:/Inetpub/wwwroot/"),
|
||||
OS.LINUX: ("/var/www/", "/var/www/html", "/var/www/htdocs", "/usr/local/apache2/htdocs", "/usr/local/www/data", "/var/apache2/htdocs", "/var/www/nginx-default", "/srv/www/htdocs") # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout
|
||||
OS.LINUX: ("/var/www/", "/var/www/html", "/var/www/htdocs", "/usr/local/apache2/htdocs", "/usr/local/www/data", "/var/apache2/htdocs", "/var/www/nginx-default", "/srv/www/htdocs", "/usr/local/var/www") # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout
|
||||
}
|
||||
|
||||
PART_RUN_CONTENT_TYPES = {
|
||||
|
||||
+5
-3
@@ -16,9 +16,11 @@ from lib.core.common import Backend
|
||||
from lib.core.common import checkFile
|
||||
from lib.core.common import dataToDumpFile
|
||||
from lib.core.common import dataToStdout
|
||||
from lib.core.common import filterNone
|
||||
from lib.core.common import getSafeExString
|
||||
from lib.core.common import isListLike
|
||||
from lib.core.common import isMultiThreadMode
|
||||
from lib.core.common import isNoneValue
|
||||
from lib.core.common import normalizeUnicode
|
||||
from lib.core.common import openFile
|
||||
from lib.core.common import prioritySortColumns
|
||||
@@ -166,7 +168,7 @@ class Dump(object):
|
||||
def currentDb(self, data):
|
||||
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB, DBMS.CACHE, DBMS.FRONTBASE):
|
||||
self.string("current database (equivalent to schema on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.DB2, DBMS.MIMERSQL, DBMS.MAXDB):
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.DB2, DBMS.MIMERSQL, DBMS.MAXDB, DBMS.VIRTUOSO):
|
||||
self.string("current database (equivalent to owner on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
|
||||
else:
|
||||
self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB)
|
||||
@@ -200,9 +202,9 @@ class Dump(object):
|
||||
self._write("%s:" % header)
|
||||
|
||||
for user in users:
|
||||
settings = userSettings[user]
|
||||
settings = filterNone(userSettings[user])
|
||||
|
||||
if settings is None:
|
||||
if isNoneValue(settings):
|
||||
stringSettings = ""
|
||||
else:
|
||||
stringSettings = " [%d]:" % len(settings)
|
||||
|
||||
@@ -58,6 +58,7 @@ class DBMS(object):
|
||||
EXTREMEDB = "eXtremeDB"
|
||||
FRONTBASE = "FrontBase"
|
||||
RAIMA = "Raima Database Manager"
|
||||
VIRTUOSO = "Virtuoso"
|
||||
|
||||
class DBMS_DIRECTORY_NAME(object):
|
||||
ACCESS = "access"
|
||||
@@ -86,6 +87,7 @@ class DBMS_DIRECTORY_NAME(object):
|
||||
EXTREMEDB = "extremedb"
|
||||
FRONTBASE = "frontbase"
|
||||
RAIMA = "raima"
|
||||
VIRTUOSO = "virtuoso"
|
||||
|
||||
class FORK(object):
|
||||
MARIADB = "MariaDB"
|
||||
@@ -400,6 +402,7 @@ class CONTENT_STATUS(object):
|
||||
class AUTH_TYPE(object):
|
||||
BASIC = "basic"
|
||||
DIGEST = "digest"
|
||||
BEARER = "bearer"
|
||||
NTLM = "ntlm"
|
||||
PKI = "pki"
|
||||
|
||||
@@ -437,3 +440,58 @@ class FUZZ_UNION_COLUMN:
|
||||
STRING = "<string>"
|
||||
INTEGER = "<integer>"
|
||||
NULL = "NULL"
|
||||
|
||||
class COLOR:
|
||||
BLUE = "\033[34m"
|
||||
BOLD_MAGENTA = "\033[35;1m"
|
||||
BOLD_GREEN = "\033[32;1m"
|
||||
BOLD_LIGHT_MAGENTA = "\033[95;1m"
|
||||
LIGHT_GRAY = "\033[37m"
|
||||
BOLD_RED = "\033[31;1m"
|
||||
BOLD_LIGHT_GRAY = "\033[37;1m"
|
||||
YELLOW = "\033[33m"
|
||||
DARK_GRAY = "\033[90m"
|
||||
BOLD_CYAN = "\033[36;1m"
|
||||
LIGHT_RED = "\033[91m"
|
||||
CYAN = "\033[36m"
|
||||
MAGENTA = "\033[35m"
|
||||
LIGHT_MAGENTA = "\033[95m"
|
||||
LIGHT_GREEN = "\033[92m"
|
||||
RESET = "\033[0m"
|
||||
BOLD_DARK_GRAY = "\033[90;1m"
|
||||
BOLD_LIGHT_YELLOW = "\033[93;1m"
|
||||
BOLD_LIGHT_RED = "\033[91;1m"
|
||||
BOLD_LIGHT_GREEN = "\033[92;1m"
|
||||
LIGHT_YELLOW = "\033[93m"
|
||||
BOLD_LIGHT_BLUE = "\033[94;1m"
|
||||
BOLD_LIGHT_CYAN = "\033[96;1m"
|
||||
LIGHT_BLUE = "\033[94m"
|
||||
BOLD_WHITE = "\033[97;1m"
|
||||
LIGHT_CYAN = "\033[96m"
|
||||
BLACK = "\033[30m"
|
||||
BOLD_YELLOW = "\033[33;1m"
|
||||
BOLD_BLUE = "\033[34;1m"
|
||||
GREEN = "\033[32m"
|
||||
WHITE = "\033[97m"
|
||||
BOLD_BLACK = "\033[30;1m"
|
||||
RED = "\033[31m"
|
||||
UNDERLINE = "\033[4m"
|
||||
|
||||
class BACKGROUND:
|
||||
BLUE = "\033[44m"
|
||||
LIGHT_GRAY = "\033[47m"
|
||||
YELLOW = "\033[43m"
|
||||
DARK_GRAY = "\033[100m"
|
||||
LIGHT_RED = "\033[101m"
|
||||
CYAN = "\033[46m"
|
||||
MAGENTA = "\033[45m"
|
||||
LIGHT_MAGENTA = "\033[105m"
|
||||
LIGHT_GREEN = "\033[102m"
|
||||
RESET = "\033[0m"
|
||||
LIGHT_YELLOW = "\033[103m"
|
||||
LIGHT_BLUE = "\033[104m"
|
||||
LIGHT_CYAN = "\033[106m"
|
||||
BLACK = "\033[40m"
|
||||
GREEN = "\033[42m"
|
||||
WHITE = "\033[107m"
|
||||
RED = "\033[41m"
|
||||
|
||||
+7
-1
@@ -20,6 +20,7 @@ from lib.core.data import paths
|
||||
from lib.core.defaults import defaults
|
||||
from lib.core.enums import MKSTEMP_PREFIX
|
||||
from lib.core.exception import SqlmapMissingDependence
|
||||
from lib.core.exception import SqlmapSystemException
|
||||
from lib.core.settings import DEV_EMAIL_ADDRESS
|
||||
from lib.core.settings import IS_WIN
|
||||
from lib.core.settings import ISSUES_PAGE
|
||||
@@ -72,7 +73,12 @@ def runGui(parser):
|
||||
tab = event.widget.nametowidget(event.widget.select())
|
||||
event.widget.configure(height=tab.winfo_reqheight())
|
||||
|
||||
window = _tkinter.Tk()
|
||||
try:
|
||||
window = _tkinter.Tk()
|
||||
except Exception as ex:
|
||||
errMsg = "unable to create GUI window ('%s')" % getSafeExString(ex)
|
||||
raise SqlmapSystemException(errMsg)
|
||||
|
||||
window.title(VERSION_STRING)
|
||||
|
||||
# Reference: https://www.holadevs.com/pregunta/64750/change-selected-tab-color-in-ttknotebook
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ try:
|
||||
|
||||
class _ColorizingStreamHandler(ColorizingStreamHandler):
|
||||
def colorize(self, message, levelno, force=False):
|
||||
if levelno in self.level_map and self.is_tty or force:
|
||||
if levelno in self.level_map and (self.is_tty or force):
|
||||
bg, fg, bold = self.level_map[levelno]
|
||||
params = []
|
||||
|
||||
|
||||
+22
-6
@@ -76,6 +76,7 @@ from lib.core.enums import ADJUST_TIME_DELAY
|
||||
from lib.core.enums import AUTH_TYPE
|
||||
from lib.core.enums import CUSTOM_LOGGING
|
||||
from lib.core.enums import DUMP_FORMAT
|
||||
from lib.core.enums import FORK
|
||||
from lib.core.enums import HTTP_HEADER
|
||||
from lib.core.enums import HTTPMETHOD
|
||||
from lib.core.enums import MKSTEMP_PREFIX
|
||||
@@ -727,7 +728,7 @@ def _setDBMS():
|
||||
|
||||
if conf.dbms not in SUPPORTED_DBMS:
|
||||
errMsg = "you provided an unsupported back-end database management "
|
||||
errMsg += "system. Supported DBMSes are as follows: %s. " % ', '.join(sorted(_ for _ in DBMS_DICT))
|
||||
errMsg += "system. Supported DBMSes are as follows: %s. " % ', '.join(sorted((_ for _ in (list(DBMS_DICT) + getPublicTypeMembers(FORK, True))), key=str.lower))
|
||||
errMsg += "If you do not know the back-end DBMS, do not provide "
|
||||
errMsg += "it and sqlmap will fingerprint it for you."
|
||||
raise SqlmapUnsupportedDBMSException(errMsg)
|
||||
@@ -1310,7 +1311,7 @@ def _setAuthCred():
|
||||
|
||||
def _setHTTPAuthentication():
|
||||
"""
|
||||
Check and set the HTTP(s) authentication method (Basic, Digest, NTLM or PKI),
|
||||
Check and set the HTTP(s) authentication method (Basic, Digest, Bearer, NTLM or PKI),
|
||||
username and password for first three methods, or PEM private key file for
|
||||
PKI authentication
|
||||
"""
|
||||
@@ -1333,9 +1334,9 @@ def _setHTTPAuthentication():
|
||||
errMsg += "but did not provide the type (e.g. --auth-type=\"basic\")"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
elif (conf.authType or "").lower() not in (AUTH_TYPE.BASIC, AUTH_TYPE.DIGEST, AUTH_TYPE.NTLM, AUTH_TYPE.PKI):
|
||||
elif (conf.authType or "").lower() not in (AUTH_TYPE.BASIC, AUTH_TYPE.DIGEST, AUTH_TYPE.BEARER, AUTH_TYPE.NTLM, AUTH_TYPE.PKI):
|
||||
errMsg = "HTTP authentication type value must be "
|
||||
errMsg += "Basic, Digest, NTLM or PKI"
|
||||
errMsg += "Basic, Digest, Bearer, NTLM or PKI"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if not conf.authFile:
|
||||
@@ -1348,6 +1349,9 @@ def _setHTTPAuthentication():
|
||||
regExp = "^(.*?):(.*?)$"
|
||||
errMsg = "HTTP %s authentication credentials " % authType
|
||||
errMsg += "value must be in format 'username:password'"
|
||||
elif authType == AUTH_TYPE.BEARER:
|
||||
conf.httpHeaders.append((HTTP_HEADER.AUTHORIZATION, "Bearer %s" % conf.authCred.strip()))
|
||||
return
|
||||
elif authType == AUTH_TYPE.NTLM:
|
||||
regExp = "^(.*\\\\.*):(.*?)$"
|
||||
errMsg = "HTTP NTLM authentication credentials value must "
|
||||
@@ -1916,7 +1920,7 @@ def _cleanupOptions():
|
||||
|
||||
def _cleanupEnvironment():
|
||||
"""
|
||||
Cleanup environment (e.g. from leftovers after --sqlmap-shell).
|
||||
Cleanup environment (e.g. from leftovers after --shell).
|
||||
"""
|
||||
|
||||
if issubclass(_http_client.socket.socket, socks.socksocket):
|
||||
@@ -1997,6 +2001,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||
kb.cache = AttribDict()
|
||||
kb.cache.addrinfo = {}
|
||||
kb.cache.content = {}
|
||||
kb.cache.comparison = {}
|
||||
kb.cache.encoding = {}
|
||||
kb.cache.alphaBoundaries = None
|
||||
kb.cache.hashRegex = None
|
||||
@@ -2484,7 +2489,9 @@ def _setHttpChunked():
|
||||
if header != HTTP_HEADER.CONTENT_LENGTH:
|
||||
self._putheader(header, *values)
|
||||
|
||||
_http_client.HTTPConnection._putheader = _http_client.HTTPConnection.putheader
|
||||
if not hasattr(_http_client.HTTPConnection, "_putheader"):
|
||||
_http_client.HTTPConnection._putheader = _http_client.HTTPConnection.putheader
|
||||
|
||||
_http_client.HTTPConnection.putheader = putheader
|
||||
|
||||
def _checkWebSocket():
|
||||
@@ -2542,10 +2549,19 @@ def _basicOptionValidation():
|
||||
errMsg = "value for option '--first' (firstChar) must be smaller than or equal to value for --last (lastChar) option"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if conf.proxyFile and not any((conf.randomAgent, conf.mobile, conf.agent, conf.requestFile)):
|
||||
warnMsg = "usage of switch '--random-agent' is strongly recommended when "
|
||||
warnMsg += "using option '--proxy-file'"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
if conf.textOnly and conf.nullConnection:
|
||||
errMsg = "switch '--text-only' is incompatible with switch '--null-connection'"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if conf.base64Parameter and conf.tamper:
|
||||
errMsg = "option '--base64' is incompatible with option '--tamper'"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if conf.eta and conf.verbose > defaults.verbose:
|
||||
errMsg = "switch '--eta' is incompatible with option '-v'"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
+16
-7
@@ -11,6 +11,7 @@ import random
|
||||
import re
|
||||
import string
|
||||
import sys
|
||||
import time
|
||||
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.enums import DBMS_DIRECTORY_NAME
|
||||
@@ -18,7 +19,7 @@ from lib.core.enums import OS
|
||||
from thirdparty.six import unichr as _unichr
|
||||
|
||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||
VERSION = "1.5.2.0"
|
||||
VERSION = "1.5.5.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)
|
||||
@@ -125,6 +126,9 @@ 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)"
|
||||
|
||||
# Google Search consent cookie
|
||||
GOOGLE_CONSENT_COOKIE = "CONSENT=YES+shp.gws-%s-0-RC1.%s+FX+740" % (time.strftime("%Y%m%d"), "".join(random.sample(string.ascii_lowercase, 2)))
|
||||
|
||||
# Regular expression used for extracting results from DuckDuckGo search
|
||||
DUCKDUCKGO_REGEX = r'<a class="result__url" href="(htt[^"]+)'
|
||||
|
||||
@@ -283,11 +287,12 @@ CACHE_SYSTEM_DBS = ("%Dictionary", "INFORMATION_SCHEMA", "%SYS")
|
||||
EXTREMEDB_SYSTEM_DBS = ("",)
|
||||
FRONTBASE_SYSTEM_DBS = ("DEFINITION_SCHEMA", "INFORMATION_SCHEMA")
|
||||
RAIMA_SYSTEM_DBS = ("",)
|
||||
VIRTUOSO_SYSTEM_DBS = ("",)
|
||||
|
||||
# Note: (<regular>) + (<forks>)
|
||||
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
|
||||
MYSQL_ALIASES = ("mysql", "my") + ("mariadb", "maria", "memsql", "tidb", "percona")
|
||||
PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg") + ("cockroach", "cockroachdb", "redshift", "greenplum", "yellowbrick", "enterprisedb", "aurora")
|
||||
MYSQL_ALIASES = ("mysql", "my") + ("mariadb", "maria", "memsql", "tidb", "percona", "drizzle")
|
||||
PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg") + ("cockroach", "cockroachdb", "amazon redshift", "redshift", "greenplum", "yellowbrick", "enterprisedb", "yugabyte", "yugabytedb")
|
||||
ORACLE_ALIASES = ("oracle", "orcl", "ora", "or")
|
||||
SQLITE_ALIASES = ("sqlite", "sqlite3")
|
||||
ACCESS_ALIASES = ("microsoft access", "msaccess", "access", "jet")
|
||||
@@ -296,7 +301,7 @@ MAXDB_ALIASES = ("max", "maxdb", "sap maxdb", "sap db")
|
||||
SYBASE_ALIASES = ("sybase", "sybase sql server")
|
||||
DB2_ALIASES = ("db2", "ibm db2", "ibmdb2")
|
||||
HSQLDB_ALIASES = ("hsql", "hsqldb", "hs", "hypersql")
|
||||
H2_ALIASES = ("h2",)
|
||||
H2_ALIASES = ("h2",) + ("ignite", "apache ignite")
|
||||
INFORMIX_ALIASES = ("informix", "ibm informix", "ibminformix")
|
||||
MONETDB_ALIASES = ("monet", "monetdb",)
|
||||
DERBY_ALIASES = ("derby", "apache derby",)
|
||||
@@ -307,17 +312,18 @@ ALTIBASE_ALIASES = ("altibase",)
|
||||
MIMERSQL_ALIASES = ("mimersql", "mimer")
|
||||
CRATEDB_ALIASES = ("cratedb", "crate")
|
||||
CUBRID_ALIASES = ("cubrid",)
|
||||
CACHE_ALIASES = ("intersystems cache", "cachedb", "cache")
|
||||
CACHE_ALIASES = ("intersystems cache", "cachedb", "cache", "iris")
|
||||
EXTREMEDB_ALIASES = ("extremedb", "extreme")
|
||||
FRONTBASE_ALIASES = ("frontbase",)
|
||||
RAIMA_ALIASES = ("raima database manager", "raima", "raimadb", "raimadm", "rdm", "rds", "velocis")
|
||||
VIRTUOSO_ALIASES = ("virtuoso", "openlink virtuoso")
|
||||
|
||||
DBMS_DIRECTORY_DICT = dict((getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_"))
|
||||
|
||||
SUPPORTED_DBMS = set(MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + H2_ALIASES + INFORMIX_ALIASES + MONETDB_ALIASES + DERBY_ALIASES + VERTICA_ALIASES + MCKOI_ALIASES + PRESTO_ALIASES + ALTIBASE_ALIASES + MIMERSQL_ALIASES + CRATEDB_ALIASES + CUBRID_ALIASES + CACHE_ALIASES + EXTREMEDB_ALIASES + RAIMA_ALIASES)
|
||||
SUPPORTED_DBMS = set(MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + H2_ALIASES + INFORMIX_ALIASES + MONETDB_ALIASES + DERBY_ALIASES + VERTICA_ALIASES + MCKOI_ALIASES + PRESTO_ALIASES + ALTIBASE_ALIASES + MIMERSQL_ALIASES + CRATEDB_ALIASES + CUBRID_ALIASES + CACHE_ALIASES + EXTREMEDB_ALIASES + RAIMA_ALIASES + VIRTUOSO_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), (DBMS.H2, H2_ALIASES), (DBMS.INFORMIX, INFORMIX_ALIASES), (DBMS.MONETDB, MONETDB_ALIASES), (DBMS.DERBY, DERBY_ALIASES), (DBMS.VERTICA, VERTICA_ALIASES), (DBMS.MCKOI, MCKOI_ALIASES), (DBMS.PRESTO, PRESTO_ALIASES), (DBMS.ALTIBASE, ALTIBASE_ALIASES), (DBMS.MIMERSQL, MIMERSQL_ALIASES), (DBMS.CRATEDB, CRATEDB_ALIASES), (DBMS.CUBRID, CUBRID_ALIASES), (DBMS.CACHE, CACHE_ALIASES), (DBMS.EXTREMEDB, EXTREMEDB_ALIASES), (DBMS.FRONTBASE, FRONTBASE_ALIASES), (DBMS.RAIMA, RAIMA_ALIASES))
|
||||
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), (DBMS.H2, H2_ALIASES), (DBMS.INFORMIX, INFORMIX_ALIASES), (DBMS.MONETDB, MONETDB_ALIASES), (DBMS.DERBY, DERBY_ALIASES), (DBMS.VERTICA, VERTICA_ALIASES), (DBMS.MCKOI, MCKOI_ALIASES), (DBMS.PRESTO, PRESTO_ALIASES), (DBMS.ALTIBASE, ALTIBASE_ALIASES), (DBMS.MIMERSQL, MIMERSQL_ALIASES), (DBMS.CRATEDB, CRATEDB_ALIASES), (DBMS.CUBRID, CUBRID_ALIASES), (DBMS.CACHE, CACHE_ALIASES), (DBMS.EXTREMEDB, EXTREMEDB_ALIASES), (DBMS.FRONTBASE, FRONTBASE_ALIASES), (DBMS.RAIMA, RAIMA_ALIASES), (DBMS.VIRTUOSO, VIRTUOSO_ALIASES))
|
||||
|
||||
USER_AGENT_ALIASES = ("ua", "useragent", "user-agent")
|
||||
REFERER_ALIASES = ("ref", "referer", "referrer")
|
||||
@@ -503,6 +509,9 @@ REFLECTED_MAX_REGEX_PARTS = 10
|
||||
# Chars which can be used as a failsafe values in case of too long URL encoding value
|
||||
URLENCODE_FAILSAFE_CHARS = "()|,"
|
||||
|
||||
# Factor used for yuge page multiplication
|
||||
YUGE_FACTOR = 1000
|
||||
|
||||
# Maximum length of URL encoded value after which failsafe procedure takes away
|
||||
URLENCODE_CHAR_LIMIT = 2000
|
||||
|
||||
|
||||
+30
-118
@@ -40,30 +40,32 @@ def vulnTest():
|
||||
TESTS = (
|
||||
("-h", ("to see full list of options run with '-hh'",)),
|
||||
("--dependencies --deprecations", ("sqlmap requires", "third-party library", "~DeprecationWarning:")),
|
||||
("-u <url> --flush-session --wizard", ("Please choose:", "back-end DBMS: SQLite", "current user is DBA: True", "banner: '3.")),
|
||||
(u"-c <config> --flush-session --roles --statements --hostname --privileges --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=U", (u": '\u0161u\u0107uraj'", "on SQLite it is not possible")),
|
||||
("-u <url> --data='reflect=1' --flush-session --wizard --disable-coloring", ("Please choose:", "back-end DBMS: SQLite", "current user is DBA: True", "banner: '3.")),
|
||||
("-u <url> --data='code=1' --code=200 --technique=B --banner --no-cast --flush-session", ("back-end DBMS: SQLite", "banner: '3.", "~COALESCE(CAST(")),
|
||||
(u"-c <config> --flush-session --output-dir=\"<tmpdir>\" --smart --roles --statements --hostname --privileges --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=U", (u": '\u0161u\u0107uraj'", "on SQLite it is not possible", "as the output directory")),
|
||||
(u"-u <url> --flush-session --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=B --no-escape --string=luther --unstable", (u": '\u0161u\u0107uraj'",)),
|
||||
("-m <multiple> --flush-session --technique=B --banner", ("URL 3:", "back-end DBMS: SQLite", "banner: '3.")),
|
||||
("--dummy", ("all tested parameters do not appear to be injectable", "does not seem to be injectable", "there is not at least one", "~might be injectable")),
|
||||
("-u '<url>&id2=1' -p id2 -v 5 --flush-session --level=5 --test-filter='AND boolean-based blind - WHERE or HAVING clause (MySQL comment)'", ("~1AND",)),
|
||||
("-u '<url>&id2=1' -p id2 -v 5 --flush-session --level=5 --text-only --test-filter='AND boolean-based blind - WHERE or HAVING clause (MySQL comment)'", ("~1AND",)),
|
||||
("--list-tampers", ("between", "MySQL", "xforwardedfor")),
|
||||
("-r <request> --flush-session -v 5 --test-skip='heavy' --save=<config>", ("CloudFlare", "web application technology: Express", "possible DBMS: 'SQLite'", "User-agent: foobar", "~Type: time-based blind", "saved command line options to the configuration file")),
|
||||
("-c <config>", ("CloudFlare", "possible DBMS: 'SQLite'", "User-agent: foobar", "~Type: time-based blind")),
|
||||
("<piped> -r <request> -l <log> --flush-session --banner --technique=B", ("banner: '3.", "STDIN")),
|
||||
("-l <log> --flush-session --keep-alive --skip-waf -v 5 --technique=U --union-from=users --banner --parse-errors", ("banner: '3.", "ORDER BY term out of range", "~xp_cmdshell", "Connection: keep-alive")),
|
||||
("-l <log> --flush-session --keep-alive --skip-waf -vvvvv --technique=U --union-from=users --banner --parse-errors", ("banner: '3.", "ORDER BY term out of range", "~xp_cmdshell", "Connection: keep-alive")),
|
||||
("-l <log> --offline --banner -v 5", ("banner: '3.", "~[TRAFFIC OUT]")),
|
||||
("-u <url> --flush-session --data='id=1&_=Eewef6oh' --chunked --randomize=_ --random-agent --banner", ("fetched random HTTP User-Agent header value", "Parameter: id (POST)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.")),
|
||||
("-u <base> --flush-session --data='id=1&_=Eewef6oh' --chunked --randomize=_ --random-agent --banner", ("fetched random HTTP User-Agent header value", "Parameter: id (POST)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.")),
|
||||
("-u <base64> -p id --base64=id --data='base64=true' --flush-session --banner --technique=B", ("banner: '3.",)),
|
||||
("-u <base64> -p id --base64=id --data='base64=true' --flush-session --tables --technique=U", (" users ",)),
|
||||
("-u <url> --flush-session --banner --technique=B --not-string 'no results'", ("banner: '3.",)),
|
||||
("-u <url> --flush-session --banner --technique=B --first=1 --last=2", ("banner: '3.'",)),
|
||||
("-u <url> --flush-session --banner --technique=B --disable-precon --not-string 'no results'", ("banner: '3.",)),
|
||||
("-u <url> --flush-session --encoding=gbk --banner --technique=B --first=1 --last=2", ("banner: '3.'",)),
|
||||
("-u <url> --flush-session --encoding=ascii --forms --crawl=2 --threads=2 --banner", ("total of 2 targets", "might be injectable", "Type: UNION query", "banner: '3.")),
|
||||
("-u <url> --flush-session --data='{\"id\": 1}' --banner", ("might be injectable", "3 columns", "Payload: {\"id\"", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.")),
|
||||
("-u <url> --flush-session -H 'Foo: Bar' -H 'Sna: Fu' --data='<root><param name=\"id\" value=\"1*\"/></root>' --union-char=1 --mobile --answers='smartphone=3' --banner --smart -v 5", ("might be injectable", "Payload: <root><param name=\"id\" value=\"1", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.", "Nexus", "Sna: Fu", "Foo: Bar")),
|
||||
("-u <url> --flush-session --method=PUT --data='a=1&b=2&c=3&id=1' --skip-static --har=<tmp> --dump -T users --start=1 --stop=2", ("might be injectable", "Parameter: id (PUT)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "2 entries")),
|
||||
("-u <url> --flush-session -H 'id: 1*' --tables -t <tmp>", ("might be injectable", "Parameter: id #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")),
|
||||
("-u <base> --flush-session --data='{\"id\": 1}' --banner", ("might be injectable", "3 columns", "Payload: {\"id\"", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.")),
|
||||
("-u <base> --flush-session -H 'Foo: Bar' -H 'Sna: Fu' --data='<root><param name=\"id\" value=\"1*\"/></root>' --union-char=1 --mobile --answers='smartphone=3' --banner --smart -v 5", ("might be injectable", "Payload: <root><param name=\"id\" value=\"1", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.", "Nexus", "Sna: Fu", "Foo: Bar")),
|
||||
("-u <base> --flush-session --method=PUT --data='a=1;id=1;b=2' --param-del=';' --skip-static --har=<tmpfile> --dump -T users --start=1 --stop=2", ("might be injectable", "Parameter: id (PUT)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "2 entries")),
|
||||
("-u <url> --flush-session -H 'id: 1*' --tables -t <tmpfile>", ("might be injectable", "Parameter: id #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")),
|
||||
("-u <url> --flush-session --banner --invalid-logical --technique=B --predict-output --test-filter='OR boolean' --tamper=space2dash", ("banner: '3.", " LIKE ")),
|
||||
("-u <url> --flush-session --cookie=\"PHPSESSID=d41d8cd98f00b204e9800998ecf8427e; id=1*; id2=2\" --tables --union-cols=3", ("might be injectable", "Cookie #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")),
|
||||
("-u <url> --flush-session --null-connection --technique=B --tamper=between,randomcase --banner", ("NULL connection is supported with HEAD method", "banner: '3.")),
|
||||
("-u <url> --flush-session --null-connection --technique=B --tamper=between,randomcase --banner --count -T users", ("NULL connection is supported with HEAD method", "banner: '3.", "users | 5")),
|
||||
("-u <url> --flush-session --parse-errors --test-filter=\"subquery\" --eval=\"import hashlib; id2=2; id3=hashlib.md5(id.encode()).hexdigest()\" --referer=\"localhost\"", ("might be injectable", ": syntax error", "back-end DBMS: SQLite", "WHERE or HAVING clause (subquery")),
|
||||
("-u <url> --banner --schema --dump -T users --binary-fields=surname --where \"id>3\"", ("banner: '3.", "INTEGER", "TEXT", "id", "name", "surname", "2 entries", "6E616D6569736E756C6C")),
|
||||
("-u <url> --technique=U --fresh-queries --force-partial --dump -T users --dump-format=HTML --answers=\"crack=n\" -v 3", ("performed 6 queries", "nameisnull", "~using default dictionary", "dumped to HTML file")),
|
||||
@@ -116,30 +118,37 @@ def vulnTest():
|
||||
handle, log = tempfile.mkstemp(suffix=".log")
|
||||
os.close(handle)
|
||||
|
||||
handle, multiple = tempfile.mkstemp(suffix=".lst")
|
||||
os.close(handle)
|
||||
|
||||
content = "POST / HTTP/1.0\nUser-agent: foobar\nHost: %s:%s\n\nid=1\n" % (address, port)
|
||||
|
||||
open(request, "w+").write(content)
|
||||
open(log, "w+").write('<port>%d</port><request base64="true"><![CDATA[%s]]></request>' % (port, encodeBase64(content, binary=False)))
|
||||
|
||||
url = "http://%s:%d/?id=1" % (address, port)
|
||||
base = "http://%s:%d/" % (address, port)
|
||||
url = "%s?id=1" % base
|
||||
direct = "sqlite3://%s" % database
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
|
||||
content = open(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.conf"))).read().replace("url =", "url = %s" % url)
|
||||
open(config, "w+").write(content)
|
||||
|
||||
open(multiple, "w+").write("%s?%s=%d\n%s?%s=%d\n%s&%s=1" % (base, randomStr(), randomInt(), base, randomStr(), randomInt(), url, randomStr()))
|
||||
|
||||
for options, checks in TESTS:
|
||||
status = '%d/%d (%d%%) ' % (count, len(TESTS), round(100.0 * count / len(TESTS)))
|
||||
dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status))
|
||||
|
||||
for tag, value in (("<url>", url), ("<direct>", direct), ("<request>", request), ("<log>", log), ("<config>", config), ("<base64>", url.replace("id=1", "id=MZ=%3d"))):
|
||||
for tag, value in (("<url>", url), ("<base>", base), ("<direct>", direct), ("<tmpdir>", tmpdir), ("<request>", request), ("<log>", log), ("<multiple>", multiple), ("<config>", config), ("<base64>", url.replace("id=1", "id=MZ=%3d"))):
|
||||
options = options.replace(tag, value)
|
||||
|
||||
cmd = "%s \"%s\" %s --batch --non-interactive --debug" % (sys.executable, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py")), options)
|
||||
|
||||
if "<tmp>" in cmd:
|
||||
if "<tmpfile>" in cmd:
|
||||
handle, tmp = tempfile.mkstemp()
|
||||
os.close(handle)
|
||||
cmd = cmd.replace("<tmp>", tmp)
|
||||
cmd = cmd.replace("<tmpfile>", tmp)
|
||||
|
||||
if "<piped>" in cmd:
|
||||
cmd = re.sub(r"<piped>\s*", "", cmd)
|
||||
@@ -162,107 +171,6 @@ def vulnTest():
|
||||
|
||||
return retVal
|
||||
|
||||
def bedTest():
|
||||
"""
|
||||
Runs the testing against 'testbed'
|
||||
"""
|
||||
|
||||
TESTS = (
|
||||
# MaxDB
|
||||
("-u 'http://testbed/maxdb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("Kernel____7.9.10___Build_003-123-265-343", "Database: DBADMIN", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'SAP MaxDB'", "the back-end DBMS is SAP MaxDB", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/maxdb/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("Kernel____7.9.10___Build_003-123-265-343", "Database: DBADMIN", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is SAP MaxDB", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/maxdb/get_int.php?id=1' --flush-session --technique=U --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Kernel____7.9.10___Build_003-123-265-343", "current database (equivalent to owner on SAP MaxDB): 'SYS'", "current user: 'DBADMIN'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||
|
||||
# Informix
|
||||
("-u 'http://testbed/informix/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("retrieved: 47", "IBM Informix Dynamic Server Version 14.10.FC2DE", "Database: testdb", "Table: users", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'Informix'", "the back-end DBMS is Informix", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/informix/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("IBM Informix Dynamic Server Version 14.10.FC2DE", "current database: 'testdb'", "current user: 'testuser'", "[1 column]", "| surname | varchar |")),
|
||||
|
||||
# Altibase
|
||||
("-u 'http://testbed/altibase/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "Database: SYS", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'Altibase'", "the back-end DBMS is Altibase", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/altibase/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "Database: SYS", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is Altibase", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/altibase/get_int.php?id=1' --flush-session --technique=U --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("x86_64-unknown-linux-gnu", "current database (equivalent to owner on Altibase): 'SYS'", "current user: 'SYS'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||
|
||||
# CockroachDB
|
||||
("-u 'http://testbed/cockroachdb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "CockroachDB fork", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'PostgreSQL'", "the back-end DBMS is PostgreSQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/cockroachdb/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "CockroachDB fork", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is PostgreSQL", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/cockroachdb/get_int.php?id=1' --flush-session --technique=E --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "CockroachDB fork", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: PostgreSQL AND error-based", "the back-end DBMS is PostgreSQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/cockroachdb/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: PostgreSQL AND error-based", "Title: PostgreSQL > 8.1 stacked queries", "Title: PostgreSQL > 8.1 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "x86_64-unknown-linux-gnu", "current database (equivalent to schema on PostgreSQL): 'public'", "current user: 'root'", "[1 column]", "| surname | varchar |")),
|
||||
|
||||
# CrateDB
|
||||
("-u 'http://testbed/cratedb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("4.0.10", "Database: doc", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'CrateDB'", "the back-end DBMS is CrateDB", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/cratedb/get_int.php?id=1' --flush-session --technique=B --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("4.0.10", "current database (equivalent to schema on CrateDB): 'doc'", "current user: 'crate'", "[1 column]", "| surname |")),
|
||||
|
||||
# Drizzle
|
||||
("-u 'http://testbed/drizzle/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("7.1.36-stable", "Drizzle fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'MySQL'", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/drizzle/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("7.1.36-stable", "Drizzle fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is MySQL", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/drizzle/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: MySQL >= 5.0.12 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "7.1.36-stable", "current database: 'testdb'", "current user: 'root'", "[1 column]", "| surname | VARCHAR |")),
|
||||
|
||||
# Firebird
|
||||
("-u 'http://testbed/firebird/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump --banner --sql-query=\"SELECT 'foobar'\"", ("banner: '2.5", "Table: USERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "possible DBMS: 'Firebird'", "the back-end DBMS is Firebird", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/firebird/get_int.php?id=1' --flush-session --technique=U --is-dba --dump --banner --sql-query=\"SELECT 'foobar'\"", ("banner: '2.5", "Table: USERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is Firebird", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/firebird/get_int.php?id=1' --flush-session --technique=U --hex --banner --current-user --search -C surname --answers='dump=n'", ("banner: '2.5", "current user: 'SYSDBA'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||
|
||||
# H2
|
||||
("-u 'http://testbed/h2/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("1.4.192", "Database: PUBLIC", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'H2'", "the back-end DBMS is H2", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/h2/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("1.4.192", "Database: PUBLIC", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is H2", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/h2/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: Generic inline queries", "Title: Generic UNION query (NULL) - 3 columns", "1.4.192", "current database (equivalent to schema on H2): 'PUBLIC'", "current user: 'SA'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||
|
||||
# HSQLDB
|
||||
("-u 'http://testbed/hsqldb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("2.3.4", "Database: PUBLIC", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'HSQLDB'", "the back-end DBMS is HSQLDB", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/hsqldb/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("2.3.4", "Database: PUBLIC", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is HSQLDB", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/hsqldb/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: HSQLDB > 2.0 AND time-based blind (heavy query)", "Title: Generic UNION query (NULL) - 3 columns", "2.3.4", "current database (equivalent to schema on HSQLDB): 'PUBLIC'", "current user: 'SA'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||
|
||||
# IBM DB2
|
||||
("-u 'http://testbed/db2/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("banner: 'DB2 v", "Database: DB2INST1", "Table: USERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'IBM DB2'", "the back-end DBMS is IBM DB2", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/db2/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("banner: 'DB2 v", "Database: DB2INST1", "Table: USERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is IBM DB2", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/db2/get_int.php?id=1' --flush-session --technique=U --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("banner: 'DB2 v", "current database (equivalent to owner on IBM DB2): 'DB2INST1'", "current user: 'DB2INST1'", "[1 column]", "| SURNAME | VARCHAR(1000) |")),
|
||||
|
||||
# MariaDB
|
||||
("-u 'http://testbed/mariadb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("10.4.12-MariaDB-1:10.4.12+maria~bionic", "MariaDB fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'MySQL'", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/mariadb/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("10.4.12-MariaDB-1:10.4.12+maria~bionic", "MariaDB fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is MySQL", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/mariadb/get_int.php?id=1' --flush-session --technique=E --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("10.4.12-MariaDB-1:10.4.12+maria~bionic", "MariaDB fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: MySQL >= 5.0 AND error-based", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/mariadb/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: MySQL >= 5.0 AND error-based", "Title: MySQL >= 5.0.12 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "10.4.12-MariaDB-1:10.4.12+maria~bionic", "current database: 'testdb'", "current user: 'root@%'", "[1 column]", "| surname | varchar(1000) |")),
|
||||
|
||||
# MySQL
|
||||
("-u 'http://testbed/mysql/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("8.0.19", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'MySQL'", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/mysql/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("8.0.19", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is MySQL", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/mysql/get_int.php?id=1' --flush-session --technique=E --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("8.0.19", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: MySQL >= 5.0 AND error-based", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/mysql/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: MySQL >= 5.1 AND error-based", "Title: MySQL >= 5.0.12 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "8.0.19", "current database: 'testdb'", "current user: 'root@%'", "[1 column]", "| surname | varchar(1000) |")),
|
||||
|
||||
# PostgreSQL
|
||||
("-u 'http://testbed/postgresql/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-pc-linux-gnu", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'PostgreSQL'", "the back-end DBMS is PostgreSQL", "current user is DBA: False", ": 'foobar'")),
|
||||
("-u 'http://testbed/postgresql/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-pc-linux-gnu", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is PostgreSQL", "appears to have 3 columns", "current user is DBA: False", ": 'foobar'")),
|
||||
("-u 'http://testbed/postgresql/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: PostgreSQL AND error-based", "Title: PostgreSQL > 8.1 stacked queries", "Title: PostgreSQL > 8.1 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "x86_64-pc-linux-gnu", "current database (equivalent to schema on PostgreSQL): 'public'", "current user: 'testuser'", "[1 column]", "| surname | varchar |")),
|
||||
)
|
||||
|
||||
retVal = True
|
||||
count = 0
|
||||
|
||||
for options, checks in TESTS:
|
||||
status = '%d/%d (%d%%) ' % (count, len(TESTS), round(100.0 * count / len(TESTS)))
|
||||
dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status))
|
||||
|
||||
cmd = "%s %s %s --batch" % (sys.executable, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py")), options)
|
||||
output = shellExec(cmd)
|
||||
|
||||
if not all((check in output if not check.startswith('~') else check[1:] not in output) for check in checks):
|
||||
for check in checks:
|
||||
if check not in output:
|
||||
print(cmd, check)
|
||||
dataToStdout("---\n\n$ %s\n" % cmd)
|
||||
dataToStdout("%s---\n" % output, coloring=False)
|
||||
retVal = False
|
||||
|
||||
count += 1
|
||||
|
||||
clearConsoleLine()
|
||||
if retVal:
|
||||
logger.info("bed test final result: PASSED")
|
||||
else:
|
||||
logger.error("best test final result: FAILED")
|
||||
|
||||
return retVal
|
||||
|
||||
def fuzzTest():
|
||||
count = 0
|
||||
address, port = "127.0.0.10", random.randint(1025, 65535)
|
||||
@@ -300,11 +208,15 @@ def fuzzTest():
|
||||
if any(_ in lines[j] for _ in ("googleDork",)):
|
||||
continue
|
||||
|
||||
if re.search(r"= (True|False)", lines[j]):
|
||||
lines[j] = lines[j].replace(" = False", " = True")
|
||||
continue
|
||||
|
||||
if lines[j].strip().endswith('='):
|
||||
lines[j] += random.sample(("True", "False", randomStr(), str(randomInt())), 1)[0]
|
||||
|
||||
k = random.randint(0, len(lines) - 1)
|
||||
if '=' in lines[k]:
|
||||
if '=' in lines[k] and not re.search(r"= (True|False)", lines[k]):
|
||||
lines[k] += chr(random.randint(0, 255))
|
||||
|
||||
open(config, "w+").write("\n".join(lines))
|
||||
|
||||
+1
-1
@@ -161,7 +161,7 @@ def update():
|
||||
if IS_WIN:
|
||||
infoMsg = "for Windows platform it's recommended "
|
||||
infoMsg += "to use a GitHub for Windows client for updating "
|
||||
infoMsg += "purposes (http://windows.github.com/) or just "
|
||||
infoMsg += "purposes (https://desktop.github.com/) or just "
|
||||
infoMsg += "download the latest snapshot from "
|
||||
infoMsg += "https://github.com/sqlmapproject/sqlmap/downloads"
|
||||
else:
|
||||
|
||||
+22
-13
@@ -193,7 +193,7 @@ def cmdLineParser(argv=None):
|
||||
help="Extra headers (e.g. \"Accept-Language: fr\\nETag: 123\")")
|
||||
|
||||
request.add_argument("--auth-type", dest="authType",
|
||||
help="HTTP authentication type (Basic, Digest, NTLM or PKI)")
|
||||
help="HTTP authentication type (Basic, Digest, Bearer, ...)")
|
||||
|
||||
request.add_argument("--auth-cred", dest="authCred",
|
||||
help="HTTP authentication credentials (name:password)")
|
||||
@@ -704,7 +704,7 @@ def cmdLineParser(argv=None):
|
||||
help="Regexp for filtering targets")
|
||||
|
||||
general.add_argument("--skip-heuristics", dest="skipHeuristics", action="store_true",
|
||||
help="Skip heuristic detection of SQLi/XSS vulnerabilities")
|
||||
help="Skip heuristic detection of vulnerabilities")
|
||||
|
||||
general.add_argument("--skip-waf", dest="skipWaf", action="store_true",
|
||||
help="Skip heuristic detection of WAF/IPS protection")
|
||||
@@ -731,7 +731,7 @@ def cmdLineParser(argv=None):
|
||||
help="Run host OS command(s) when SQL injection is found")
|
||||
|
||||
miscellaneous.add_argument("--beep", dest="beep", action="store_true",
|
||||
help="Beep on question and/or when SQLi/XSS/FI is found")
|
||||
help="Beep on question and/or when vulnerability is found")
|
||||
|
||||
miscellaneous.add_argument("--dependencies", dest="dependencies", action="store_true",
|
||||
help="Check for missing (optional) sqlmap dependencies")
|
||||
@@ -751,7 +751,7 @@ def cmdLineParser(argv=None):
|
||||
miscellaneous.add_argument("--results-file", dest="resultsFile",
|
||||
help="Location of CSV results file in multiple targets mode")
|
||||
|
||||
miscellaneous.add_argument("--sqlmap-shell", dest="sqlmapShell", action="store_true",
|
||||
miscellaneous.add_argument("--shell", dest="shell", action="store_true",
|
||||
help="Prompt for an interactive sqlmap shell")
|
||||
|
||||
miscellaneous.add_argument("--tmp-dir", dest="tmpDir",
|
||||
@@ -773,6 +773,9 @@ def cmdLineParser(argv=None):
|
||||
parser.add_argument("--dummy", dest="dummy", action="store_true",
|
||||
help=SUPPRESS)
|
||||
|
||||
parser.add_argument("--yuge", dest="yuge", action="store_true",
|
||||
help=SUPPRESS)
|
||||
|
||||
parser.add_argument("--murphy-rate", dest="murphyRate", type=int,
|
||||
help=SUPPRESS)
|
||||
|
||||
@@ -794,6 +797,9 @@ def cmdLineParser(argv=None):
|
||||
parser.add_argument("--profile", dest="profile", action="store_true",
|
||||
help=SUPPRESS)
|
||||
|
||||
parser.add_argument("--localhost", dest="localhost", action="store_true",
|
||||
help=SUPPRESS)
|
||||
|
||||
parser.add_argument("--force-dbms", dest="forceDbms",
|
||||
help=SUPPRESS)
|
||||
|
||||
@@ -818,9 +824,6 @@ def cmdLineParser(argv=None):
|
||||
parser.add_argument("--vuln-test", dest="vulnTest", action="store_true",
|
||||
help=SUPPRESS)
|
||||
|
||||
parser.add_argument("--bed-test", dest="bedTest", action="store_true",
|
||||
help=SUPPRESS)
|
||||
|
||||
parser.add_argument("--fuzz-test", dest="fuzzTest", action="store_true",
|
||||
help=SUPPRESS)
|
||||
|
||||
@@ -894,7 +897,7 @@ def cmdLineParser(argv=None):
|
||||
|
||||
raise SqlmapSilentQuitException
|
||||
|
||||
elif "--sqlmap-shell" in argv:
|
||||
elif "--shell" in argv:
|
||||
_createHomeDirectories()
|
||||
|
||||
parser.usage = ""
|
||||
@@ -907,14 +910,17 @@ def cmdLineParser(argv=None):
|
||||
|
||||
while True:
|
||||
command = None
|
||||
prompt = "sqlmap > "
|
||||
|
||||
try:
|
||||
# Note: in Python2 command should not be converted to Unicode before passing to shlex (Reference: https://bugs.python.org/issue1170)
|
||||
command = _input("sqlmap-shell> ").strip()
|
||||
command = _input(prompt).strip()
|
||||
except (KeyboardInterrupt, EOFError):
|
||||
print()
|
||||
raise SqlmapShellQuitException
|
||||
|
||||
command = re.sub(r"(?i)\Anew\s+", "", command or "")
|
||||
|
||||
if not command:
|
||||
continue
|
||||
elif command.lower() == "clear":
|
||||
@@ -924,8 +930,9 @@ def cmdLineParser(argv=None):
|
||||
elif command.lower() in ("x", "q", "exit", "quit"):
|
||||
raise SqlmapShellQuitException
|
||||
elif command[0] != '-':
|
||||
dataToStdout("[!] invalid option(s) provided\n")
|
||||
dataToStdout("[i] proper example: '-u http://www.site.com/vuln.php?id=1 --banner'\n")
|
||||
if not re.search(r"(?i)\A(\?|help)\Z", command):
|
||||
dataToStdout("[!] invalid option(s) provided\n")
|
||||
dataToStdout("[i] valid example: '-u http://www.site.com/vuln.php?id=1 --banner'\n")
|
||||
else:
|
||||
saveHistory(AUTOCOMPLETE_TYPE.SQLMAP)
|
||||
loadHistory(AUTOCOMPLETE_TYPE.SQLMAP)
|
||||
@@ -969,6 +976,8 @@ def cmdLineParser(argv=None):
|
||||
argv[i] = ""
|
||||
elif argv[i].startswith("--data-raw"):
|
||||
argv[i] = argv[i].replace("--data-raw", "--data", 1)
|
||||
elif argv[i].startswith("--auth-creds"):
|
||||
argv[i] = argv[i].replace("--auth-creds", "--auth-cred", 1)
|
||||
elif argv[i].startswith("--drop-cookie"):
|
||||
argv[i] = argv[i].replace("--drop-cookie", "--drop-set-cookie", 1)
|
||||
elif any(argv[i].startswith(_) for _ in ("--tamper", "--ignore-code", "--skip")):
|
||||
@@ -1056,8 +1065,8 @@ def cmdLineParser(argv=None):
|
||||
else:
|
||||
args.stdinPipe = None
|
||||
|
||||
if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.vulnTest, args.bedTest, args.fuzzTest, args.wizard, args.dependencies, args.purge, args.listTampers, args.hashFile, args.stdinPipe)):
|
||||
errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, --list-tampers, --wizard, --update, --purge or --dependencies). "
|
||||
if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.vulnTest, args.fuzzTest, args.wizard, args.dependencies, args.purge, args.listTampers, args.hashFile, args.stdinPipe)):
|
||||
errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, --wizard, --shell, --update, --purge, --list-tampers or --dependencies). "
|
||||
errMsg += "Use -h for basic and -hh for advanced help\n"
|
||||
parser.error(errMsg)
|
||||
|
||||
|
||||
@@ -259,7 +259,7 @@ def getHeuristicCharEncoding(page):
|
||||
"""
|
||||
|
||||
key = hash(page)
|
||||
retVal = kb.cache.encoding.get(key) or detect(page[:HEURISTIC_PAGE_SIZE_THRESHOLD])["encoding"]
|
||||
retVal = kb.cache.encoding[key] if key in kb.cache.encoding else detect(page[:HEURISTIC_PAGE_SIZE_THRESHOLD])["encoding"]
|
||||
kb.cache.encoding[key] = retVal
|
||||
|
||||
if retVal and retVal.lower().replace('-', "") == UNICODE_ENCODING.lower().replace('-', ""):
|
||||
|
||||
@@ -151,10 +151,20 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
|
||||
seq1 = seq1.split("\n")
|
||||
seq2 = seq2.split("\n")
|
||||
|
||||
key = None
|
||||
else:
|
||||
key = (hash(seq1), hash(seq2))
|
||||
|
||||
seqMatcher.set_seq1(seq1)
|
||||
seqMatcher.set_seq2(seq2)
|
||||
|
||||
ratio = round(seqMatcher.quick_ratio() if not kb.heavilyDynamic else seqMatcher.ratio(), 3)
|
||||
if key in kb.cache.comparison:
|
||||
ratio = kb.cache.comparison[key]
|
||||
else:
|
||||
ratio = round(seqMatcher.quick_ratio() if not kb.heavilyDynamic else seqMatcher.ratio(), 3)
|
||||
|
||||
if key:
|
||||
kb.cache.comparison[key] = ratio
|
||||
|
||||
# If the url is stable and we did not set yet the match ratio and the
|
||||
# current injected value changes the url page content
|
||||
|
||||
+18
-4
@@ -126,6 +126,7 @@ from lib.core.settings import UNICODE_ENCODING
|
||||
from lib.core.settings import URI_HTTP_HEADER
|
||||
from lib.core.settings import WARN_TIME_STDEV
|
||||
from lib.core.settings import WEBSOCKET_INITIAL_TIMEOUT
|
||||
from lib.core.settings import YUGE_FACTOR
|
||||
from lib.request.basic import decodePage
|
||||
from lib.request.basic import forgeHeaders
|
||||
from lib.request.basic import processResponse
|
||||
@@ -252,6 +253,9 @@ class Connect(object):
|
||||
singleTimeWarnMessage(warnMsg)
|
||||
break
|
||||
|
||||
if conf.yuge:
|
||||
retVal = YUGE_FACTOR * retVal
|
||||
|
||||
return retVal
|
||||
|
||||
@staticmethod
|
||||
@@ -488,6 +492,9 @@ class Connect(object):
|
||||
header, value = line.split(':', 1)
|
||||
headers[header] = value
|
||||
|
||||
if conf.localhost:
|
||||
headers[HTTP_HEADER.HOST] = "localhost"
|
||||
|
||||
for key, value in list(headers.items()):
|
||||
del headers[key]
|
||||
if isinstance(value, six.string_types):
|
||||
@@ -498,8 +505,6 @@ class Connect(object):
|
||||
if six.PY2:
|
||||
url = getBytes(url) # Note: Python3 requires text while Python2 has problems when mixing text with binary POST
|
||||
|
||||
post = getBytes(post)
|
||||
|
||||
if webSocket:
|
||||
ws = websocket.WebSocket()
|
||||
ws.settimeout(WEBSOCKET_INITIAL_TIMEOUT if kb.webSocketRecvCount is None else timeout)
|
||||
@@ -543,6 +548,8 @@ class Connect(object):
|
||||
|
||||
logger.log(CUSTOM_LOGGING.TRAFFIC_OUT, requestMsg)
|
||||
else:
|
||||
post = getBytes(post)
|
||||
|
||||
if target and cmdLineOptions.method or method and method not in (HTTPMETHOD.GET, HTTPMETHOD.POST):
|
||||
req = MethodRequest(url, post, headers)
|
||||
req.set_method(cmdLineOptions.method or method)
|
||||
@@ -747,7 +754,9 @@ class Connect(object):
|
||||
if ex.code not in (conf.ignoreCode or []):
|
||||
if ex.code == _http_client.UNAUTHORIZED:
|
||||
errMsg = "not authorized, try to provide right HTTP "
|
||||
errMsg += "authentication type and valid credentials (%d)" % code
|
||||
errMsg += "authentication type and valid credentials (%d). " % code
|
||||
errMsg += "If this is intended, try to rerun by providing "
|
||||
errMsg += "a valid value for option '--ignore-code'"
|
||||
raise SqlmapConnectionException(errMsg)
|
||||
elif chunked and ex.code in (_http_client.METHOD_NOT_ALLOWED, _http_client.LENGTH_REQUIRED):
|
||||
warnMsg = "turning off HTTP chunked transfer encoding "
|
||||
@@ -780,7 +789,7 @@ class Connect(object):
|
||||
debugMsg = "got HTTP error code: %d ('%s')" % (code, status)
|
||||
logger.debug(debugMsg)
|
||||
|
||||
except (_urllib.error.URLError, socket.error, socket.timeout, _http_client.HTTPException, struct.error, binascii.Error, ProxyError, SqlmapCompressionException, WebSocketException, TypeError, ValueError, OverflowError):
|
||||
except (_urllib.error.URLError, socket.error, socket.timeout, _http_client.HTTPException, struct.error, binascii.Error, ProxyError, SqlmapCompressionException, WebSocketException, TypeError, ValueError, OverflowError, AttributeError):
|
||||
tbMsg = traceback.format_exc()
|
||||
|
||||
if conf.debug:
|
||||
@@ -788,6 +797,11 @@ class Connect(object):
|
||||
|
||||
if checking:
|
||||
return None, None, None
|
||||
elif "AttributeError:" in tbMsg:
|
||||
if "WSAECONNREFUSED" in tbMsg:
|
||||
return None, None, None
|
||||
else:
|
||||
raise
|
||||
elif "no host given" in tbMsg:
|
||||
warnMsg = "invalid URL address used (%s)" % repr(url)
|
||||
raise SqlmapSyntaxException(warnMsg)
|
||||
|
||||
@@ -198,7 +198,7 @@ def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, char
|
||||
# forge the SQL limiting the query output one entry at a time
|
||||
# NOTE: we assume that only queries that get data from a table
|
||||
# can return multiple entries
|
||||
if fromUser and " FROM " in expression.upper() and ((Backend.getIdentifiedDbms() not in FROM_DUMMY_TABLE) or (Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and not expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) and not re.search(SQL_SCALAR_REGEX, expression, re.I):
|
||||
if fromUser and " FROM " in expression.upper() and ((Backend.getIdentifiedDbms() not in FROM_DUMMY_TABLE) or (Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and not expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) and not re.search(SQL_SCALAR_REGEX, expression, re.I) and hasattr(queries[Backend.getIdentifiedDbms()].limitregexp, "query"):
|
||||
expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression)
|
||||
|
||||
if limitCond:
|
||||
|
||||
+1
-1
@@ -130,7 +130,7 @@ class UDF(object):
|
||||
errMsg = "udfSetLocalPaths() method must be defined within the plugin"
|
||||
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||
|
||||
def udfCreateFromSharedLib(self, udf=None, inpRet=None):
|
||||
def udfCreateFromSharedLib(self, udf, inpRet):
|
||||
errMsg = "udfCreateFromSharedLib() method must be defined within the plugin"
|
||||
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ from lib.core.common import goGoodSamaritan
|
||||
from lib.core.common import hashDBRetrieve
|
||||
from lib.core.common import hashDBWrite
|
||||
from lib.core.common import incrementCounter
|
||||
from lib.core.common import isListLike
|
||||
from lib.core.common import safeStringFormat
|
||||
from lib.core.common import singleTimeWarnMessage
|
||||
from lib.core.data import conf
|
||||
@@ -217,7 +218,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||
|
||||
markingValue = "'%s'" % CHAR_INFERENCE_MARK
|
||||
unescapedCharValue = unescaper.escape("'%s'" % decodeIntToUnicode(posValue))
|
||||
forgedPayload = agent.extractPayload(payload)
|
||||
forgedPayload = agent.extractPayload(payload) or ""
|
||||
forgedPayload = safeStringFormat(forgedPayload.replace(INFERENCE_GREATER_CHAR, INFERENCE_EQUALS_CHAR), (expressionUnescaped, idx, posValue)).replace(markingValue, unescapedCharValue)
|
||||
result = Request.queryPage(agent.replacePayload(payload, forgedPayload), timeBasedCompare=timeBasedCompare, raise404=False)
|
||||
incrementCounter(getTechnique())
|
||||
@@ -504,6 +505,10 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||
else:
|
||||
break
|
||||
|
||||
# NOTE: https://github.com/sqlmapproject/sqlmap/issues/4629
|
||||
if not isListLike(threadData.shared.value):
|
||||
break
|
||||
|
||||
with kb.locks.value:
|
||||
threadData.shared.value[currentCharIndex - 1 - firstChar] = val
|
||||
currentValue = list(threadData.shared.value)
|
||||
|
||||
@@ -104,6 +104,7 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
|
||||
|
||||
if kb.orderByColumns is None and (lowerCount == 1 or conf.uCols): # Note: ORDER BY is not bullet-proof
|
||||
found = _orderByTechnique(lowerCount, upperCount) if conf.uCols else _orderByTechnique()
|
||||
|
||||
if found:
|
||||
kb.orderByColumns = found
|
||||
infoMsg = "target URL appears to have %d column%s in query" % (found, 's' if found > 1 else "")
|
||||
@@ -122,8 +123,10 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
|
||||
query = agent.forgeUnionQuery('', -1, count, comment, prefix, suffix, kb.uChar, where)
|
||||
payload = agent.payload(place=place, parameter=parameter, newValue=query, where=where)
|
||||
page, headers, code = Request.queryPage(payload, place=place, content=True, raise404=False)
|
||||
|
||||
if not isNullValue(kb.uChar):
|
||||
pages[count] = page
|
||||
|
||||
ratio = comparison(page, headers, code, getRatioValue=True) or MIN_RATIO
|
||||
ratios.append(ratio)
|
||||
min_, max_ = min(min_, ratio), max(max_, ratio)
|
||||
|
||||
@@ -25,6 +25,7 @@ from lib.core.common import hashDBRetrieve
|
||||
from lib.core.common import hashDBWrite
|
||||
from lib.core.common import incrementCounter
|
||||
from lib.core.common import initTechnique
|
||||
from lib.core.common import isDigit
|
||||
from lib.core.common import isListLike
|
||||
from lib.core.common import isNoneValue
|
||||
from lib.core.common import isNumPosStrValue
|
||||
@@ -186,25 +187,25 @@ def configUnion(char=None, columns=None):
|
||||
kb.uChar = char
|
||||
|
||||
if conf.uChar is not None:
|
||||
kb.uChar = char.replace("[CHAR]", conf.uChar if conf.uChar.isdigit() else "'%s'" % conf.uChar.strip("'"))
|
||||
kb.uChar = char.replace("[CHAR]", conf.uChar if isDigit(conf.uChar) else "'%s'" % conf.uChar.strip("'"))
|
||||
|
||||
def _configUnionCols(columns):
|
||||
if not isinstance(columns, six.string_types):
|
||||
return
|
||||
|
||||
columns = columns.replace(" ", "")
|
||||
if "-" in columns:
|
||||
colsStart, colsStop = columns.split("-")
|
||||
columns = columns.replace(' ', "")
|
||||
if '-' in columns:
|
||||
colsStart, colsStop = columns.split('-')
|
||||
else:
|
||||
colsStart, colsStop = columns, columns
|
||||
|
||||
if not colsStart.isdigit() or not colsStop.isdigit():
|
||||
if not isDigit(colsStart) or not isDigit(colsStop):
|
||||
raise SqlmapSyntaxException("--union-cols must be a range of integers")
|
||||
|
||||
conf.uColsStart, conf.uColsStop = int(colsStart), int(colsStop)
|
||||
|
||||
if conf.uColsStart > conf.uColsStop:
|
||||
errMsg = "--union-cols range has to be from lower to "
|
||||
errMsg = "--union-cols range has to represent lower to "
|
||||
errMsg += "higher number of columns"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
@@ -329,8 +330,8 @@ def unionUse(expression, unpack=True, dump=False):
|
||||
|
||||
if stopLimit > TURN_OFF_RESUME_INFO_LIMIT:
|
||||
kb.suppressResumeInfo = True
|
||||
debugMsg = "suppressing possible resume console info because of "
|
||||
debugMsg += "large number of rows. It might take too long"
|
||||
debugMsg = "suppressing possible resume console info for "
|
||||
debugMsg += "large number of rows as it might take too long"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
try:
|
||||
|
||||
+19
-17
@@ -13,22 +13,6 @@ except: # removed ImportError because of https://github.com/sqlmapproject/sqlma
|
||||
from thirdparty.fcrypt.fcrypt import crypt
|
||||
|
||||
_multiprocessing = None
|
||||
try:
|
||||
import multiprocessing
|
||||
|
||||
# problems on FreeBSD (Reference: https://web.archive.org/web/20110710041353/http://www.eggheadcafe.com/microsoft/Python/35880259/multiprocessing-on-freebsd.aspx)
|
||||
_ = multiprocessing.Queue()
|
||||
|
||||
# problems with ctypes (Reference: https://github.com/sqlmapproject/sqlmap/issues/2952)
|
||||
_ = multiprocessing.Value('i')
|
||||
except (ImportError, OSError, AttributeError):
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
if multiprocessing.cpu_count() > 1:
|
||||
_multiprocessing = multiprocessing
|
||||
except NotImplementedError:
|
||||
pass
|
||||
|
||||
import base64
|
||||
import binascii
|
||||
@@ -983,6 +967,24 @@ def dictionaryAttack(attack_dict):
|
||||
|
||||
if conf.disableMulti:
|
||||
_multiprocessing = None
|
||||
else:
|
||||
# Note: https://github.com/sqlmapproject/sqlmap/issues/4367
|
||||
try:
|
||||
import multiprocessing
|
||||
|
||||
# problems on FreeBSD (Reference: https://web.archive.org/web/20110710041353/http://www.eggheadcafe.com/microsoft/Python/35880259/multiprocessing-on-freebsd.aspx)
|
||||
_ = multiprocessing.Queue()
|
||||
|
||||
# problems with ctypes (Reference: https://github.com/sqlmapproject/sqlmap/issues/2952)
|
||||
_ = multiprocessing.Value('i')
|
||||
except (ImportError, OSError, AttributeError):
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
if multiprocessing.cpu_count() > 1:
|
||||
_multiprocessing = multiprocessing
|
||||
except NotImplementedError:
|
||||
pass
|
||||
|
||||
for (_, hashes) in attack_dict.items():
|
||||
for hash_ in hashes:
|
||||
@@ -1133,7 +1135,7 @@ def dictionaryAttack(attack_dict):
|
||||
custom_wordlist.append(normalizeUnicode(user))
|
||||
|
||||
# Algorithms without extra arguments (e.g. salt and/or username)
|
||||
if hash_regex in (HASH.MYSQL, HASH.MYSQL_OLD, HASH.MD5_GENERIC, HASH.SHA1_GENERIC, HASH.SHA224_GENERIC, HASH.SHA256_GENERIC, HASH.SHA384_GENERIC, HASH.SHA512_GENERIC, HASH.APACHE_SHA1, HASH.VBULLETIN, HASH.VBULLETIN_OLD):
|
||||
if hash_regex in (HASH.MYSQL, HASH.MYSQL_OLD, HASH.MD5_GENERIC, HASH.SHA1_GENERIC, HASH.SHA224_GENERIC, HASH.SHA256_GENERIC, HASH.SHA384_GENERIC, HASH.SHA512_GENERIC, HASH.APACHE_SHA1):
|
||||
for suffix in suffix_list:
|
||||
if not attack_info or processException:
|
||||
break
|
||||
|
||||
+3
-1
@@ -28,6 +28,7 @@ from lib.core.exception import SqlmapUserQuitException
|
||||
from lib.core.settings import BING_REGEX
|
||||
from lib.core.settings import DUCKDUCKGO_REGEX
|
||||
from lib.core.settings import DUMMY_SEARCH_USER_AGENT
|
||||
from lib.core.settings import GOOGLE_CONSENT_COOKIE
|
||||
from lib.core.settings import GOOGLE_REGEX
|
||||
from lib.core.settings import HTTP_ACCEPT_ENCODING_HEADER_VALUE
|
||||
from lib.core.settings import UNICODE_ENCODING
|
||||
@@ -52,6 +53,7 @@ def _search(dork):
|
||||
|
||||
requestHeaders[HTTP_HEADER.USER_AGENT] = dict(conf.httpHeaders).get(HTTP_HEADER.USER_AGENT, DUMMY_SEARCH_USER_AGENT)
|
||||
requestHeaders[HTTP_HEADER.ACCEPT_ENCODING] = HTTP_ACCEPT_ENCODING_HEADER_VALUE
|
||||
requestHeaders[HTTP_HEADER.COOKIE] = GOOGLE_CONSENT_COOKIE
|
||||
|
||||
try:
|
||||
req = _urllib.request.Request("https://www.google.com/ncr", headers=requestHeaders)
|
||||
@@ -63,7 +65,7 @@ def _search(dork):
|
||||
gpage = conf.googlePage if conf.googlePage > 1 else 1
|
||||
logger.info("using search result page #%d" % gpage)
|
||||
|
||||
url = "https://www.google.com/search?"
|
||||
url = "https://www.google.com/search?" # NOTE: if consent fails, try to use the "http://"
|
||||
url += "q=%s&" % urlencode(dork, convall=True)
|
||||
url += "num=100&hl=en&complete=0&safe=off&filter=0&btnG=Search"
|
||||
url += "&start=%d" % ((gpage - 1) * 100)
|
||||
|
||||
+11
-2
@@ -101,13 +101,22 @@ class SQLAlchemy(GenericConnector):
|
||||
return None
|
||||
|
||||
def execute(self, query):
|
||||
retVal = False
|
||||
|
||||
try:
|
||||
self.cursor = self.connector.execute(query)
|
||||
retVal = True
|
||||
except (_sqlalchemy.exc.OperationalError, _sqlalchemy.exc.ProgrammingError) as ex:
|
||||
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(ex))
|
||||
except _sqlalchemy.exc.InternalError as ex:
|
||||
raise SqlmapConnectionException(getSafeExString(ex))
|
||||
|
||||
return retVal
|
||||
|
||||
def select(self, query):
|
||||
self.execute(query)
|
||||
return self.fetchall()
|
||||
retVal = None
|
||||
|
||||
if self.execute(query):
|
||||
retVal = self.fetchall()
|
||||
|
||||
return retVal
|
||||
|
||||
@@ -150,7 +150,8 @@ class Fingerprint(GenericFingerprint):
|
||||
"Vista or 2008": ("6.0", (2, 1)),
|
||||
"7 or 2008 R2": ("6.1", (1, 0)),
|
||||
"8 or 2012": ("6.2", (0,)),
|
||||
"8.1 or 2012 R2": ("6.3", (0,))
|
||||
"8.1 or 2012 R2": ("6.3", (0,)),
|
||||
"10 or 2016 or 2019": ("10.0", (0,))
|
||||
}
|
||||
|
||||
# Get back-end DBMS underlying operating system version
|
||||
|
||||
@@ -5,35 +5,18 @@ Copyright (c) 2006-2021 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'LICENSE' for copying permission
|
||||
"""
|
||||
|
||||
import binascii
|
||||
|
||||
from lib.core.common import isDBMSVersionAtLeast
|
||||
from lib.core.convert import getBytes
|
||||
from lib.core.convert import getUnicode
|
||||
from lib.core.convert import getOrds
|
||||
from plugins.generic.syntax import Syntax as GenericSyntax
|
||||
|
||||
class Syntax(GenericSyntax):
|
||||
@staticmethod
|
||||
def escape(expression, quote=True):
|
||||
"""
|
||||
>>> from lib.core.common import Backend
|
||||
>>> Backend.setVersion('2')
|
||||
['2']
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT 'abcdefgh' FROM foobar"
|
||||
True
|
||||
>>> Backend.setVersion('3')
|
||||
['3']
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT CAST(X'6162636465666768' AS TEXT) FROM foobar"
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT CHAR(97,98,99,100,101,102,103,104) FROM foobar"
|
||||
True
|
||||
"""
|
||||
|
||||
def escaper(value):
|
||||
# Reference: http://stackoverflow.com/questions/3444335/how-do-i-quote-a-utf-8-string-literal-in-sqlite3
|
||||
return "CAST(X'%s' AS TEXT)" % getUnicode(binascii.hexlify(getBytes(value)))
|
||||
return "CHAR(%s)" % ','.join("%d" % _ for _ in getOrds(value))
|
||||
|
||||
retVal = expression
|
||||
|
||||
if isDBMSVersionAtLeast('3'):
|
||||
retVal = Syntax._escape(expression, quote, escaper)
|
||||
|
||||
return retVal
|
||||
return Syntax._escape(expression, quote, escaper)
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2021 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'LICENSE' for copying permission
|
||||
"""
|
||||
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.settings import VIRTUOSO_SYSTEM_DBS
|
||||
from lib.core.unescaper import unescaper
|
||||
from plugins.dbms.virtuoso.enumeration import Enumeration
|
||||
from plugins.dbms.virtuoso.filesystem import Filesystem
|
||||
from plugins.dbms.virtuoso.fingerprint import Fingerprint
|
||||
from plugins.dbms.virtuoso.syntax import Syntax
|
||||
from plugins.dbms.virtuoso.takeover import Takeover
|
||||
from plugins.generic.misc import Miscellaneous
|
||||
|
||||
class VirtuosoMap(Syntax, Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||
"""
|
||||
This class defines Virtuoso methods
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.excludeDbsList = VIRTUOSO_SYSTEM_DBS
|
||||
|
||||
for cls in self.__class__.__bases__:
|
||||
cls.__init__(self)
|
||||
|
||||
unescaper[DBMS.VIRTUOSO] = Syntax.escape
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2021 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'LICENSE' for copying permission
|
||||
"""
|
||||
|
||||
from lib.core.exception import SqlmapUnsupportedFeatureException
|
||||
from plugins.generic.connector import Connector as GenericConnector
|
||||
|
||||
class Connector(GenericConnector):
|
||||
def connect(self):
|
||||
errMsg = "on Virtuoso it is not (currently) possible to establish a "
|
||||
errMsg += "direct connection"
|
||||
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2021 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'LICENSE' for copying permission
|
||||
"""
|
||||
|
||||
from lib.core.data import logger
|
||||
from plugins.generic.enumeration import Enumeration as GenericEnumeration
|
||||
|
||||
class Enumeration(GenericEnumeration):
|
||||
def getPasswordHashes(self):
|
||||
warnMsg = "on Virtuoso it is not possible to enumerate the user password hashes"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
return {}
|
||||
|
||||
def getPrivileges(self, *args, **kwargs):
|
||||
warnMsg = "on Virtuoso it is not possible to enumerate the user privileges"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
return {}
|
||||
|
||||
def getRoles(self, *args, **kwargs):
|
||||
warnMsg = "on Virtuoso it is not possible to enumerate the user roles"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
return {}
|
||||
|
||||
def searchDb(self):
|
||||
warnMsg = "on Virtuoso it is not possible to search databases"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
return []
|
||||
|
||||
def searchTable(self):
|
||||
warnMsg = "on Virtuoso it is not possible to search tables"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
return []
|
||||
|
||||
def searchColumn(self):
|
||||
warnMsg = "on Virtuoso it is not possible to search columns"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
return []
|
||||
|
||||
def search(self):
|
||||
warnMsg = "on Virtuoso search option is not available"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
def getStatements(self):
|
||||
warnMsg = "on Virtuoso it is not possible to enumerate the SQL statements"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
return []
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2021 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'LICENSE' for copying permission
|
||||
"""
|
||||
|
||||
from lib.core.exception import SqlmapUnsupportedFeatureException
|
||||
from plugins.generic.filesystem import Filesystem as GenericFilesystem
|
||||
|
||||
class Filesystem(GenericFilesystem):
|
||||
def readFile(self, remoteFile):
|
||||
errMsg = "on Virtuoso it is not possible to read files"
|
||||
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||
|
||||
def writeFile(self, localFile, remoteFile, fileType=None, forceCheck=False):
|
||||
errMsg = "on Virtuoso it is not possible to write files"
|
||||
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2021 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'LICENSE' 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 VIRTUOSO_ALIASES
|
||||
from lib.request import inject
|
||||
from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
|
||||
|
||||
class Fingerprint(GenericFingerprint):
|
||||
def __init__(self):
|
||||
GenericFingerprint.__init__(self, DBMS.VIRTUOSO)
|
||||
|
||||
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.VIRTUOSO
|
||||
return value
|
||||
|
||||
actVer = Format.getDbms()
|
||||
blank = " " * 15
|
||||
value += "active fingerprint: %s" % actVer
|
||||
|
||||
if kb.bannerFp:
|
||||
banVer = kb.bannerFp.get("dbmsVersion")
|
||||
|
||||
if banVer:
|
||||
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(VIRTUOSO_ALIASES):
|
||||
setDbms(DBMS.VIRTUOSO)
|
||||
return True
|
||||
|
||||
infoMsg = "testing %s" % DBMS.VIRTUOSO
|
||||
logger.info(infoMsg)
|
||||
|
||||
result = inject.checkBooleanExpression("GET_KEYWORD(NULL,NULL) IS NULL")
|
||||
|
||||
if result:
|
||||
infoMsg = "confirming %s" % DBMS.VIRTUOSO
|
||||
logger.info(infoMsg)
|
||||
|
||||
result = inject.checkBooleanExpression("RDF_NOW_IMPL() IS NOT NULL")
|
||||
|
||||
if not result:
|
||||
warnMsg = "the back-end DBMS is not %s" % DBMS.VIRTUOSO
|
||||
logger.warn(warnMsg)
|
||||
|
||||
return False
|
||||
|
||||
setDbms(DBMS.VIRTUOSO)
|
||||
|
||||
return True
|
||||
else:
|
||||
warnMsg = "the back-end DBMS is not %s" % DBMS.VIRTUOSO
|
||||
logger.warn(warnMsg)
|
||||
|
||||
return False
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2021 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'LICENSE' for copying permission
|
||||
"""
|
||||
|
||||
from lib.core.convert import getOrds
|
||||
from plugins.generic.syntax import Syntax as GenericSyntax
|
||||
|
||||
class Syntax(GenericSyntax):
|
||||
@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"
|
||||
True
|
||||
"""
|
||||
|
||||
def escaper(value):
|
||||
return "||".join("CHR(%d)" % _ for _ in getOrds(value))
|
||||
|
||||
return Syntax._escape(expression, quote, escaper)
|
||||
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2021 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'LICENSE' for copying permission
|
||||
"""
|
||||
|
||||
from lib.core.exception import SqlmapUnsupportedFeatureException
|
||||
from plugins.generic.takeover import Takeover as GenericTakeover
|
||||
|
||||
class Takeover(GenericTakeover):
|
||||
def osCmd(self):
|
||||
errMsg = "on Virtuoso it is not possible to execute commands"
|
||||
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||
|
||||
def osShell(self):
|
||||
errMsg = "on Virtuoso it is not possible to execute commands"
|
||||
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||
|
||||
def osPwn(self):
|
||||
errMsg = "on Virtuoso it is not possible to establish an "
|
||||
errMsg += "out-of-band connection"
|
||||
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||
|
||||
def osSmb(self):
|
||||
errMsg = "on Virtuoso it is not possible to establish an "
|
||||
errMsg += "out-of-band connection"
|
||||
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||
@@ -63,20 +63,20 @@ class Connector(object):
|
||||
|
||||
def connect(self):
|
||||
errMsg = "'connect' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
errMsg += "inside the specific DBMS plugin"
|
||||
raise SqlmapUndefinedMethod(errMsg)
|
||||
|
||||
def fetchall(self):
|
||||
errMsg = "'fetchall' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
errMsg += "inside the specific DBMS plugin"
|
||||
raise SqlmapUndefinedMethod(errMsg)
|
||||
|
||||
def execute(self, query):
|
||||
errMsg = "'execute' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
errMsg += "inside the specific DBMS plugin"
|
||||
raise SqlmapUndefinedMethod(errMsg)
|
||||
|
||||
def select(self, query):
|
||||
errMsg = "'select' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
errMsg += "inside the specific DBMS plugin"
|
||||
raise SqlmapUndefinedMethod(errMsg)
|
||||
|
||||
@@ -21,6 +21,7 @@ from lib.core.dicts import SQL_STATEMENTS
|
||||
from lib.core.enums import AUTOCOMPLETE_TYPE
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.exception import SqlmapNoneDataException
|
||||
from lib.core.settings import METADB_SUFFIX
|
||||
from lib.core.settings import NULL
|
||||
from lib.core.settings import PARAMETER_SPLITTING_REGEX
|
||||
from lib.core.shell import autoCompletion
|
||||
@@ -56,6 +57,8 @@ class Custom(object):
|
||||
if match and match.group(2).count('.') == 1:
|
||||
query = query.replace(match.group(0), "%s%s" % (match.group(1), match.group(2).replace('.', ".dbo.")))
|
||||
|
||||
query = re.sub(r"(?i)\w+%s\.?" % METADB_SUFFIX, "", query)
|
||||
|
||||
output = inject.getValue(query, fromUser=True)
|
||||
|
||||
return output
|
||||
|
||||
@@ -398,7 +398,7 @@ class Databases(object):
|
||||
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.getIdentifiedDbms() in (DBMS.HSQLDB, DBMS.INFORMIX, DBMS.FRONTBASE):
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.HSQLDB, DBMS.INFORMIX, DBMS.FRONTBASE, DBMS.VIRTUOSO):
|
||||
query = rootQuery.blind.query % (index, unsafeSQLIdentificatorNaming(db))
|
||||
else:
|
||||
query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(db), index)
|
||||
@@ -594,7 +594,7 @@ class Databases(object):
|
||||
if conf.db is not None and len(kb.data.cachedColumns) > 0 \
|
||||
and conf.db in kb.data.cachedColumns and tbl in \
|
||||
kb.data.cachedColumns[conf.db]:
|
||||
infoMsg = "fetched tables' columns on "
|
||||
infoMsg = "fetched table columns from "
|
||||
infoMsg += "database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
||||
logger.info(infoMsg)
|
||||
|
||||
@@ -614,12 +614,12 @@ class Databases(object):
|
||||
condQueryStr = "%%s%s" % colCondParam
|
||||
condQuery = " AND (%s)" % " OR ".join(condQueryStr % (condition, unsafeSQLIdentificatorNaming(col)) for col in sorted(colList))
|
||||
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.FRONTBASE):
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.FRONTBASE, DBMS.VIRTUOSO):
|
||||
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
|
||||
query += condQuery
|
||||
|
||||
if Backend.isFork(FORK.DRIZZLE):
|
||||
query = query.replace("column_type", "data_type")
|
||||
query = re.sub("column_type", "data_type", query, flags=re.I)
|
||||
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
||||
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl.upper()), unsafeSQLIdentificatorNaming(conf.db.upper()))
|
||||
@@ -730,7 +730,7 @@ class Databases(object):
|
||||
if conf.db is not None and len(kb.data.cachedColumns) > 0 \
|
||||
and conf.db in kb.data.cachedColumns and tbl in \
|
||||
kb.data.cachedColumns[conf.db]:
|
||||
infoMsg = "fetched tables' columns on "
|
||||
infoMsg = "fetched table columns from "
|
||||
infoMsg += "database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
||||
logger.info(infoMsg)
|
||||
|
||||
@@ -750,7 +750,7 @@ class Databases(object):
|
||||
condQueryStr = "%%s%s" % colCondParam
|
||||
condQuery = " AND (%s)" % " OR ".join(condQueryStr % (condition, unsafeSQLIdentificatorNaming(col)) for col in sorted(colList))
|
||||
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.FRONTBASE):
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.FRONTBASE, DBMS.VIRTUOSO):
|
||||
query = rootQuery.blind.count % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
|
||||
query += condQuery
|
||||
|
||||
@@ -819,7 +819,7 @@ class Databases(object):
|
||||
continue
|
||||
|
||||
for index in getLimitRange(count):
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.FRONTBASE):
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.FRONTBASE, DBMS.VIRTUOSO):
|
||||
query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
|
||||
query += condQuery
|
||||
field = None
|
||||
@@ -873,7 +873,7 @@ class Databases(object):
|
||||
singleTimeWarnMessage(warnMsg)
|
||||
|
||||
if not onlyColNames:
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.FRONTBASE):
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.FRONTBASE, DBMS.VIRTUOSO):
|
||||
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl), column, unsafeSQLIdentificatorNaming(conf.db))
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
||||
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl.upper()), column, unsafeSQLIdentificatorNaming(conf.db.upper()))
|
||||
@@ -1050,7 +1050,7 @@ class Databases(object):
|
||||
query = rootQuery.blind.count
|
||||
|
||||
if Backend.isFork(FORK.DRIZZLE):
|
||||
query = query.replace("INFORMATION_SCHEMA", "DATA_DICTIONARY")
|
||||
query = re.sub("INFORMATION_SCHEMA", "DATA_DICTIONARY", query, flags=re.I)
|
||||
|
||||
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
||||
|
||||
@@ -1078,7 +1078,7 @@ class Databases(object):
|
||||
query = rootQuery.blind.query % index
|
||||
|
||||
if Backend.isFork(FORK.DRIZZLE):
|
||||
query = query.replace("INFORMATION_SCHEMA", "DATA_DICTIONARY")
|
||||
query = re.sub("INFORMATION_SCHEMA", "DATA_DICTIONARY", query, flags=re.I)
|
||||
|
||||
value = unArrayizeValue(inject.getValue(query, union=False, error=False))
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ class Entries(object):
|
||||
singleTimeLogMessage(infoMsg)
|
||||
return
|
||||
|
||||
conf.db = safeSQLIdentificatorNaming(conf.db)
|
||||
conf.db = safeSQLIdentificatorNaming(conf.db) or ""
|
||||
|
||||
if conf.tbl:
|
||||
if Backend.getIdentifiedDbms() in UPPER_CASE_DBMSES:
|
||||
@@ -101,7 +101,7 @@ class Entries(object):
|
||||
|
||||
if tblList and isListLike(tblList[0]):
|
||||
tblList = tblList[0]
|
||||
elif not conf.search:
|
||||
elif conf.db and not conf.search:
|
||||
errMsg = "unable to retrieve the tables "
|
||||
errMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
||||
raise SqlmapNoneDataException(errMsg)
|
||||
@@ -190,7 +190,7 @@ class Entries(object):
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL):
|
||||
# Partial inband and error
|
||||
if not (isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) and kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.ORIGINAL):
|
||||
table = "%s.%s" % (conf.db, tbl)
|
||||
table = "%s.%s" % (conf.db, tbl) if conf.db else tbl
|
||||
|
||||
if Backend.isDbms(DBMS.MSSQL) and not conf.forcePivoting:
|
||||
warnMsg = "in case of table dumping problems (e.g. column entry order) "
|
||||
@@ -239,7 +239,7 @@ class Entries(object):
|
||||
entries = BigArray(_zip(*[entries[colName] for colName in colList]))
|
||||
else:
|
||||
query = rootQuery.inband.query % (colString, conf.db, tbl)
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE):
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.VIRTUOSO):
|
||||
query = rootQuery.inband.query % (colString, conf.db, tbl, prioritySortColumns(colList)[0])
|
||||
else:
|
||||
query = rootQuery.inband.query % (colString, conf.db, tbl)
|
||||
@@ -297,7 +297,7 @@ class Entries(object):
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.MAXDB, DBMS.ACCESS, DBMS.FIREBIRD, DBMS.MCKOI, DBMS.EXTREMEDB, DBMS.RAIMA):
|
||||
query = rootQuery.blind.count % tbl
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL):
|
||||
query = rootQuery.blind.count % ("%s.%s" % (conf.db, tbl))
|
||||
query = rootQuery.blind.count % ("%s.%s" % (conf.db, tbl)) if conf.db else tbl
|
||||
elif Backend.isDbms(DBMS.INFORMIX):
|
||||
query = rootQuery.blind.count % (conf.db, tbl)
|
||||
else:
|
||||
@@ -334,9 +334,9 @@ class Entries(object):
|
||||
if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI, DBMS.RAIMA):
|
||||
table = tbl
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL, DBMS.MAXDB):
|
||||
table = "%s.%s" % (conf.db, tbl)
|
||||
table = "%s.%s" % (conf.db, tbl) if conf.db else tbl
|
||||
elif Backend.isDbms(DBMS.INFORMIX):
|
||||
table = "%s:%s" % (conf.db, tbl)
|
||||
table = "%s:%s" % (conf.db, tbl) if conf.db else tbl
|
||||
|
||||
if Backend.isDbms(DBMS.MSSQL) and not conf.forcePivoting:
|
||||
warnMsg = "in case of table dumping problems (e.g. column entry order) "
|
||||
@@ -418,7 +418,7 @@ class Entries(object):
|
||||
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):
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.INFORMIX, DBMS.VIRTUOSO):
|
||||
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), conf.db, tbl, sorted(colList, key=len)[0])
|
||||
elif Backend.isDbms(DBMS.FRONTBASE):
|
||||
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), conf.db, tbl)
|
||||
|
||||
@@ -276,7 +276,7 @@ class Users(object):
|
||||
if user in retrievedUsers:
|
||||
continue
|
||||
|
||||
if Backend.isDbms(DBMS.INFORMIX):
|
||||
if Backend.getIdentifiedDbms() in (DBMS.INFORMIX, DBMS.VIRTUOSO):
|
||||
count = 1
|
||||
else:
|
||||
infoMsg = "fetching number of password hashes "
|
||||
@@ -322,7 +322,7 @@ class Users(object):
|
||||
if fallback:
|
||||
query = query.replace("master.dbo.fn_varbintohexstr", "sys.fn_sqlvarbasetostr")
|
||||
|
||||
elif Backend.isDbms(DBMS.INFORMIX):
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.INFORMIX, DBMS.VIRTUOSO):
|
||||
query = rootQuery.blind.query % (user,)
|
||||
|
||||
elif Backend.isDbms(DBMS.HSQLDB):
|
||||
|
||||
+3
-3
@@ -87,12 +87,12 @@ headers = Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9
|
||||
Accept-Charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
|
||||
|
||||
# HTTP Authentication type. Useful only if the target URL requires
|
||||
# HTTP Basic, Digest or NTLM authentication and you have such data.
|
||||
# Valid: Basic, Digest, NTLM or PKI
|
||||
# HTTP Basic, Digest, Bearer or NTLM authentication and you have such data.
|
||||
# Valid: Basic, Digest, Bearer, NTLM or PKI
|
||||
authType =
|
||||
|
||||
# HTTP authentication credentials. Useful only if the target URL requires
|
||||
# HTTP Basic, Digest or NTLM authentication and you have such data.
|
||||
# HTTP Basic, Digest, Token or NTLM authentication and you have such data.
|
||||
# Syntax: username:password
|
||||
authCred =
|
||||
|
||||
|
||||
@@ -175,9 +175,6 @@ def main():
|
||||
elif conf.vulnTest:
|
||||
from lib.core.testing import vulnTest
|
||||
os._exitcode = 1 - (vulnTest() or 0)
|
||||
elif conf.bedTest:
|
||||
from lib.core.testing import bedTest
|
||||
os._exitcode = 1 - (bedTest() or 0)
|
||||
elif conf.fuzzTest:
|
||||
from lib.core.testing import fuzzTest
|
||||
fuzzTest()
|
||||
@@ -193,6 +190,8 @@ def main():
|
||||
targets = getFileItems(conf.bulkFile)
|
||||
|
||||
for i in xrange(len(targets)):
|
||||
target = None
|
||||
|
||||
try:
|
||||
kb.targets.clear()
|
||||
target = targets[i]
|
||||
@@ -205,7 +204,7 @@ def main():
|
||||
|
||||
crawl(target)
|
||||
except Exception as ex:
|
||||
if not isinstance(ex, SqlmapUserQuitException):
|
||||
if target and not isinstance(ex, SqlmapUserQuitException):
|
||||
errMsg = "problem occurred while crawling '%s' ('%s')" % (target, getSafeExString(ex))
|
||||
logger.error(errMsg)
|
||||
else:
|
||||
@@ -387,6 +386,12 @@ def main():
|
||||
logger.critical(errMsg)
|
||||
raise SystemExit
|
||||
|
||||
elif "'WebSocket' object has no attribute 'status'" in excMsg:
|
||||
errMsg = "wrong websocket library detected"
|
||||
errMsg += " (Reference: 'https://github.com/sqlmapproject/sqlmap/issues/4572#issuecomment-775041086')"
|
||||
logger.critical(errMsg)
|
||||
raise SystemExit
|
||||
|
||||
elif all(_ in excMsg for _ in ("window = tkinter.Tk()",)):
|
||||
errMsg = "there has been a problem in initialization of GUI interface "
|
||||
errMsg += "('%s')" % excMsg.strip().split('\n')[-1]
|
||||
@@ -436,6 +441,11 @@ def main():
|
||||
logger.critical(errMsg)
|
||||
raise SystemExit
|
||||
|
||||
elif all(_ in excMsg for _ in ("No such file", "sqlmap.conf", "Test")):
|
||||
errMsg = "you are trying to run (hidden) development tests inside the production environment"
|
||||
logger.critical(errMsg)
|
||||
raise SystemExit
|
||||
|
||||
elif all(_ in excMsg for _ in ("HTTPNtlmAuthHandler", "'str' object has no attribute 'decode'")):
|
||||
errMsg = "package 'python-ntlm' has a known compatibility issue with the "
|
||||
errMsg += "Python 3 (Reference: 'https://github.com/mullender/python-ntlm/pull/61')"
|
||||
|
||||
Vendored
+12
@@ -303,6 +303,12 @@
|
||||
"9bf2:RVdXum61OElCWapAYKYPk4JzWOtohM4IiUYMr2RXg1uQJbX2uhdOn9htOj+hX7AB16FcPxJPdLsXo2tKaK99n+i7c4RmkgI2FZjxtDtAeq+c3qA4chS1XKTC"
|
||||
]
|
||||
},
|
||||
"duedge": {
|
||||
"company": "Baidu",
|
||||
"name": "DuEdge",
|
||||
"regex": "(?s)<h1>403<small>.+DuEdge Event ID: [0-9a-f]{16}.+IP: [0-9.]+",
|
||||
"signatures": []
|
||||
},
|
||||
"expressionengine": {
|
||||
"company": "EllisLab",
|
||||
"name": "ExpressionEngine",
|
||||
@@ -536,6 +542,12 @@
|
||||
"125a:RVdXum61OElCWKpAYKYPk4JzWOtohM4JiUcMr2RXg1uQJbX3uhdOn9htOj+hX7AB16FcPxJPdLsXo2tLaK99n+i7c4VmkwI3FZnxtDtBeq+c36A5chW1XaTC"
|
||||
]
|
||||
},
|
||||
"openrasp": {
|
||||
"company": "Blackbaud",
|
||||
"name": "OpenRASP",
|
||||
"regex": "400 - Request blocked by OpenRASP|https://rasp.baidu.com/blocked2?/",
|
||||
"signatures": []
|
||||
},
|
||||
"paloalto": {
|
||||
"company": "Palo Alto Networks",
|
||||
"name": "Palo Alto",
|
||||
|
||||
Vendored
+2
-2
@@ -165,11 +165,11 @@ class ConnectionManager:
|
||||
|
||||
def get_ready_conn(self, host):
|
||||
conn = None
|
||||
self._lock.acquire()
|
||||
try:
|
||||
self._lock.acquire()
|
||||
if host in self._hostmap:
|
||||
for c in self._hostmap[host]:
|
||||
if self._readymap[c]:
|
||||
if self._readymap.get(c):
|
||||
self._readymap[c] = 0
|
||||
conn = c
|
||||
break
|
||||
|
||||
Reference in New Issue
Block a user