Compare commits

...

10 Commits
1.5.4 ... 1.5.5

Author SHA1 Message Date
Miroslav Stampar
aee2bee856 Fixes #4664 2021-05-01 11:39:42 +02:00
Miroslav Stampar
cfa7b3c3bd Implements #4656 2021-04-28 18:06:15 +02:00
Miroslav Stampar
76b310cc43 Fixes #4650 2021-04-25 20:36:19 +02:00
Miroslav Stampar
9a6acd2054 Fixes #4637 2021-04-13 17:55:54 +02:00
Miroslav Stampar
387020ece8 Better yet for #4633 2021-04-09 11:43:01 +02:00
Miroslav Stampar
732b9670d2 Minor fix related to last commit 2021-04-05 19:00:35 +02:00
Miroslav Stampar
1159c9ccae Fixes #4629 2021-04-05 18:38:47 +02:00
Miroslav Stampar
cadbf170f0 Fixes #4630 2021-04-05 18:21:09 +02:00
Miroslav Stampar
fc486c8b34 Minor update 2021-04-02 13:55:37 +02:00
Miroslav Stampar
cfe43e3f2b Patch for #4626 2021-04-02 12:56:31 +02:00
9 changed files with 47 additions and 33 deletions

View File

@@ -16,9 +16,11 @@ from lib.core.common import Backend
from lib.core.common import checkFile from lib.core.common import checkFile
from lib.core.common import dataToDumpFile from lib.core.common import dataToDumpFile
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import filterNone
from lib.core.common import getSafeExString from lib.core.common import getSafeExString
from lib.core.common import isListLike from lib.core.common import isListLike
from lib.core.common import isMultiThreadMode from lib.core.common import isMultiThreadMode
from lib.core.common import isNoneValue
from lib.core.common import normalizeUnicode from lib.core.common import normalizeUnicode
from lib.core.common import openFile from lib.core.common import openFile
from lib.core.common import prioritySortColumns from lib.core.common import prioritySortColumns
@@ -200,9 +202,9 @@ class Dump(object):
self._write("%s:" % header) self._write("%s:" % header)
for user in users: for user in users:
settings = userSettings[user] settings = filterNone(userSettings[user])
if settings is None: if isNoneValue(settings):
stringSettings = "" stringSettings = ""
else: else:
stringSettings = " [%d]:" % len(settings) stringSettings = " [%d]:" % len(settings)

View File

@@ -11,6 +11,7 @@ import random
import re import re
import string import string
import sys import sys
import time
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import DBMS_DIRECTORY_NAME 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 from thirdparty.six import unichr as _unichr
# sqlmap version (<major>.<minor>.<month>.<monthly commit>) # sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.5.4.0" VERSION = "1.5.5.0"
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE) VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
@@ -125,6 +126,9 @@ MAX_MURPHY_SLEEP_TIME = 3
# Regular expression used for extracting results from Google search # Regular expression used for extracting results from Google search
GOOGLE_REGEX = r"webcache\.googleusercontent\.com/search\?q=cache:[^:]+:([^+]+)\+&amp;cd=|url\?\w+=((?![^>]+webcache\.googleusercontent\.com)http[^>]+)&(sa=U|rct=j)" GOOGLE_REGEX = r"webcache\.googleusercontent\.com/search\?q=cache:[^:]+:([^+]+)\+&amp;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 # Regular expression used for extracting results from DuckDuckGo search
DUCKDUCKGO_REGEX = r'<a class="result__url" href="(htt[^"]+)' DUCKDUCKGO_REGEX = r'<a class="result__url" href="(htt[^"]+)'

View File

@@ -26,6 +26,7 @@ from lib.core.common import goGoodSamaritan
from lib.core.common import hashDBRetrieve from lib.core.common import hashDBRetrieve
from lib.core.common import hashDBWrite from lib.core.common import hashDBWrite
from lib.core.common import incrementCounter from lib.core.common import incrementCounter
from lib.core.common import isListLike
from lib.core.common import safeStringFormat from lib.core.common import safeStringFormat
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage
from lib.core.data import conf from lib.core.data import conf
@@ -504,6 +505,10 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
else: else:
break break
# NOTE: https://github.com/sqlmapproject/sqlmap/issues/4629
if not isListLike(threadData.shared.value):
break
with kb.locks.value: with kb.locks.value:
threadData.shared.value[currentCharIndex - 1 - firstChar] = val threadData.shared.value[currentCharIndex - 1 - firstChar] = val
currentValue = list(threadData.shared.value) currentValue = list(threadData.shared.value)

View File

@@ -28,6 +28,7 @@ from lib.core.exception import SqlmapUserQuitException
from lib.core.settings import BING_REGEX from lib.core.settings import BING_REGEX
from lib.core.settings import DUCKDUCKGO_REGEX from lib.core.settings import DUCKDUCKGO_REGEX
from lib.core.settings import DUMMY_SEARCH_USER_AGENT 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 GOOGLE_REGEX
from lib.core.settings import HTTP_ACCEPT_ENCODING_HEADER_VALUE from lib.core.settings import HTTP_ACCEPT_ENCODING_HEADER_VALUE
from lib.core.settings import UNICODE_ENCODING 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.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.ACCEPT_ENCODING] = HTTP_ACCEPT_ENCODING_HEADER_VALUE
requestHeaders[HTTP_HEADER.COOKIE] = GOOGLE_CONSENT_COOKIE
try: try:
req = _urllib.request.Request("https://www.google.com/ncr", headers=requestHeaders) 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 gpage = conf.googlePage if conf.googlePage > 1 else 1
logger.info("using search result page #%d" % gpage) 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 += "q=%s&" % urlencode(dork, convall=True)
url += "num=100&hl=en&complete=0&safe=off&filter=0&btnG=Search" url += "num=100&hl=en&complete=0&safe=off&filter=0&btnG=Search"
url += "&start=%d" % ((gpage - 1) * 100) url += "&start=%d" % ((gpage - 1) * 100)

View File

@@ -5,35 +5,18 @@ Copyright (c) 2006-2021 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import binascii from lib.core.convert import getOrds
from lib.core.common import isDBMSVersionAtLeast
from lib.core.convert import getBytes
from lib.core.convert import getUnicode
from plugins.generic.syntax import Syntax as GenericSyntax from plugins.generic.syntax import Syntax as GenericSyntax
class Syntax(GenericSyntax): class Syntax(GenericSyntax):
@staticmethod @staticmethod
def escape(expression, quote=True): def escape(expression, quote=True):
""" """
>>> from lib.core.common import Backend >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT CHAR(97,98,99,100,101,102,103,104) FROM foobar"
>>> 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"
True True
""" """
def escaper(value): def escaper(value):
# Reference: http://stackoverflow.com/questions/3444335/how-do-i-quote-a-utf-8-string-literal-in-sqlite3 return "CHAR(%s)" % ','.join("%d" % _ for _ in getOrds(value))
return "CAST(X'%s' AS TEXT)" % getUnicode(binascii.hexlify(getBytes(value)))
retVal = expression return Syntax._escape(expression, quote, escaper)
if isDBMSVersionAtLeast('3'):
retVal = Syntax._escape(expression, quote, escaper)
return retVal

View File

@@ -86,7 +86,7 @@ class Entries(object):
singleTimeLogMessage(infoMsg) singleTimeLogMessage(infoMsg)
return return
conf.db = safeSQLIdentificatorNaming(conf.db) conf.db = safeSQLIdentificatorNaming(conf.db) or ""
if conf.tbl: if conf.tbl:
if Backend.getIdentifiedDbms() in UPPER_CASE_DBMSES: if Backend.getIdentifiedDbms() in UPPER_CASE_DBMSES:
@@ -101,7 +101,7 @@ class Entries(object):
if tblList and isListLike(tblList[0]): if tblList and isListLike(tblList[0]):
tblList = tblList[0] tblList = tblList[0]
elif not conf.search: elif conf.db and not conf.search:
errMsg = "unable to retrieve the tables " errMsg = "unable to retrieve the tables "
errMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db) errMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
raise SqlmapNoneDataException(errMsg) raise SqlmapNoneDataException(errMsg)
@@ -190,7 +190,7 @@ class Entries(object):
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL): elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL):
# Partial inband and error # Partial inband and error
if not (isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) and kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.ORIGINAL): 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: if Backend.isDbms(DBMS.MSSQL) and not conf.forcePivoting:
warnMsg = "in case of table dumping problems (e.g. column entry order) " warnMsg = "in case of table dumping problems (e.g. column entry order) "
@@ -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): elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.MAXDB, DBMS.ACCESS, DBMS.FIREBIRD, DBMS.MCKOI, DBMS.EXTREMEDB, DBMS.RAIMA):
query = rootQuery.blind.count % tbl query = rootQuery.blind.count % tbl
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL): 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): elif Backend.isDbms(DBMS.INFORMIX):
query = rootQuery.blind.count % (conf.db, tbl) query = rootQuery.blind.count % (conf.db, tbl)
else: else:
@@ -334,9 +334,9 @@ class Entries(object):
if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI, DBMS.RAIMA): if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI, DBMS.RAIMA):
table = tbl table = tbl
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL, DBMS.MAXDB): 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): 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: if Backend.isDbms(DBMS.MSSQL) and not conf.forcePivoting:
warnMsg = "in case of table dumping problems (e.g. column entry order) " warnMsg = "in case of table dumping problems (e.g. column entry order) "

View File

@@ -386,6 +386,12 @@ def main():
logger.critical(errMsg) logger.critical(errMsg)
raise SystemExit 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()",)): elif all(_ in excMsg for _ in ("window = tkinter.Tk()",)):
errMsg = "there has been a problem in initialization of GUI interface " errMsg = "there has been a problem in initialization of GUI interface "
errMsg += "('%s')" % excMsg.strip().split('\n')[-1] errMsg += "('%s')" % excMsg.strip().split('\n')[-1]

View File

@@ -303,6 +303,12 @@
"9bf2:RVdXum61OElCWapAYKYPk4JzWOtohM4IiUYMr2RXg1uQJbX2uhdOn9htOj+hX7AB16FcPxJPdLsXo2tKaK99n+i7c4RmkgI2FZjxtDtAeq+c3qA4chS1XKTC" "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": { "expressionengine": {
"company": "EllisLab", "company": "EllisLab",
"name": "ExpressionEngine", "name": "ExpressionEngine",
@@ -536,6 +542,12 @@
"125a:RVdXum61OElCWKpAYKYPk4JzWOtohM4JiUcMr2RXg1uQJbX3uhdOn9htOj+hX7AB16FcPxJPdLsXo2tLaK99n+i7c4VmkwI3FZnxtDtBeq+c36A5chW1XaTC" "125a:RVdXum61OElCWKpAYKYPk4JzWOtohM4JiUcMr2RXg1uQJbX3uhdOn9htOj+hX7AB16FcPxJPdLsXo2tLaK99n+i7c4VmkwI3FZnxtDtBeq+c36A5chW1XaTC"
] ]
}, },
"openrasp": {
"company": "Blackbaud",
"name": "OpenRASP",
"regex": "400 - Request blocked by OpenRASP|https://rasp.baidu.com/blocked2?/",
"signatures": []
},
"paloalto": { "paloalto": {
"company": "Palo Alto Networks", "company": "Palo Alto Networks",
"name": "Palo Alto", "name": "Palo Alto",

View File

@@ -165,11 +165,11 @@ class ConnectionManager:
def get_ready_conn(self, host): def get_ready_conn(self, host):
conn = None conn = None
self._lock.acquire()
try: try:
self._lock.acquire()
if host in self._hostmap: if host in self._hostmap:
for c in self._hostmap[host]: for c in self._hostmap[host]:
if self._readymap[c]: if self._readymap.get(c):
self._readymap[c] = 0 self._readymap[c] = 0
conn = c conn = c
break break