From f494004f44fc8825f963961c7136957d8e370674 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Thu, 10 Sep 2015 15:51:33 +0200 Subject: [PATCH] Switching to the getSafeExString (where it can be used) --- lib/controller/checks.py | 7 ++++--- lib/controller/controller.py | 3 ++- lib/core/common.py | 23 +++++++++++++++++++---- lib/core/dump.py | 5 +++-- lib/core/option.py | 4 ++-- lib/parse/configfile.py | 3 ++- lib/request/connect.py | 31 ++++++++++++++++--------------- lib/request/httpshandler.py | 5 +++-- lib/utils/api.py | 3 ++- lib/utils/google.py | 3 ++- lib/utils/hash.py | 3 ++- lib/utils/hashdb.py | 5 +++-- plugins/generic/entries.py | 5 +++-- sqlmap.py | 3 ++- tamper/symboliclogical.py | 2 +- 15 files changed, 66 insertions(+), 39 deletions(-) diff --git a/lib/controller/checks.py b/lib/controller/checks.py index 6f266702f..2cb131ad3 100644 --- a/lib/controller/checks.py +++ b/lib/controller/checks.py @@ -22,6 +22,7 @@ from lib.core.common import findDynamicContent from lib.core.common import Format from lib.core.common import getLastRequestHTTPError from lib.core.common import getPublicTypeMembers +from lib.core.common import getSafeExString from lib.core.common import getSortedInjectionTests from lib.core.common import getUnicode from lib.core.common import intersect @@ -1279,7 +1280,7 @@ def checkNullConnection(): logger.info(infoMsg) except SqlmapConnectionException, ex: - errMsg = getUnicode(ex.message) + errMsg = getSafeExString(ex) raise SqlmapConnectionException(errMsg) finally: @@ -1298,7 +1299,7 @@ def checkConnection(suppressOutput=False): raise SqlmapConnectionException(errMsg) except socket.error, ex: errMsg = "problem occurred while " - errMsg += "resolving a host name '%s' ('%s')" % (conf.hostname, ex.message) + errMsg += "resolving a host name '%s' ('%s')" % (conf.hostname, getSafeExString(ex)) raise SqlmapConnectionException(errMsg) if not suppressOutput and not conf.dummy and not conf.offline: @@ -1336,7 +1337,7 @@ def checkConnection(suppressOutput=False): singleTimeWarnMessage(warnMsg) if any(code in kb.httpErrorCodes for code in (httplib.NOT_FOUND, )): - errMsg = getUnicode(ex.message) + errMsg = getSafeExString(ex) logger.critical(errMsg) if conf.multipleTargets: diff --git a/lib/controller/controller.py b/lib/controller/controller.py index d5793767c..0e82a7c23 100644 --- a/lib/controller/controller.py +++ b/lib/controller/controller.py @@ -24,6 +24,7 @@ from lib.core.common import dataToStdout from lib.core.common import extractRegexResult from lib.core.common import getFilteredPageContent from lib.core.common import getPublicTypeMembers +from lib.core.common import getSafeExString from lib.core.common import getUnicode from lib.core.common import hashDBRetrieve from lib.core.common import hashDBWrite @@ -648,7 +649,7 @@ def start(): raise except SqlmapBaseException, ex: - errMsg = getUnicode(ex.message) + errMsg = getSafeExString(ex) if conf.multipleTargets: errMsg += ", skipping to the next %s" % ("form" if conf.forms else "URL") diff --git a/lib/core/common.py b/lib/core/common.py index 5f906cd8a..de7ce354c 100755 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -879,7 +879,7 @@ def dataToOutFile(filename, data): f.write(data) except IOError, ex: errMsg = "something went wrong while trying to write " - errMsg += "to the output file ('%s')" % ex.message + errMsg += "to the output file ('%s')" % getSafeExString(ex) raise SqlmapGenericException(errMsg) return retVal @@ -3008,7 +3008,7 @@ def createGithubIssue(errMsg, excMsg): else: warnMsg = "something went wrong while creating a Github issue" if ex: - warnMsg += " ('%s')" % ex.message + warnMsg += " ('%s')" % getSafeExString(ex) if "Unauthorized" in warnMsg: warnMsg += ". Please update to the latest revision" logger.warn(warnMsg) @@ -3567,7 +3567,7 @@ def findPageForms(content, url, raise_=False, addToTargets=False): request = form.click() except (ValueError, TypeError), ex: errMsg = "there has been a problem while " - errMsg += "processing page forms ('%s')" % ex.message + errMsg += "processing page forms ('%s')" % getSafeExString(ex) if raise_: raise SqlmapGenericException(errMsg) else: @@ -3670,7 +3670,7 @@ def evaluateCode(code, variables=None): except KeyboardInterrupt: raise except Exception, ex: - errMsg = "an error occurred while evaluating provided code ('%s') " % ex.message + errMsg = "an error occurred while evaluating provided code ('%s') " % getSafeExString(ex) raise SqlmapGenericException(errMsg) def serializeObject(object_): @@ -3977,3 +3977,18 @@ def pollProcess(process, suppress_errors=False): dataToStdout(" quit unexpectedly with return code %d\n" % returncode) break + +def getSafeExString(ex): + """ + Safe way how to get the proper exception represtation as a string + (Note: errors to be avoided: 1) "%s" % Exception(u'\u0161') and 2) "%s" % str(Exception(u'\u0161')) + """ + + retVal = ex + + if getattr(ex, "message", None): + retVal = ex.message + elif getattr(ex, "msg", None): + retVal = ex.msg + + return getUnicode(retVal) diff --git a/lib/core/dump.py b/lib/core/dump.py index 4401f1742..a4ff91913 100644 --- a/lib/core/dump.py +++ b/lib/core/dump.py @@ -15,6 +15,7 @@ import threading from lib.core.common import Backend from lib.core.common import dataToDumpFile from lib.core.common import dataToStdout +from lib.core.common import getSafeExString from lib.core.common import getUnicode from lib.core.common import isListLike from lib.core.common import normalizeUnicode @@ -74,7 +75,7 @@ class Dump(object): try: self._outputFP.write(text) except IOError, ex: - errMsg = "error occurred while writing to log file ('%s')" % ex.message + errMsg = "error occurred while writing to log file ('%s')" % getSafeExString(ex) raise SqlmapGenericException(errMsg) if kb.get("multiThreadMode"): @@ -94,7 +95,7 @@ class Dump(object): try: self._outputFP = openFile(self._outputFile, "ab" if not conf.flushSession else "wb") except IOError, ex: - errMsg = "error occurred while opening log file ('%s')" % ex.message + errMsg = "error occurred while opening log file ('%s')" % getSafeExString(ex) raise SqlmapGenericException(errMsg) def getOutputFile(self): diff --git a/lib/core/option.py b/lib/core/option.py index ebef4b311..e9d4331b9 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -1523,7 +1523,7 @@ def _createTemporaryDirectory(): os.makedirs(tempfile.gettempdir()) except IOError, ex: errMsg = "there has been a problem while accessing " - errMsg += "system's temporary directory location(s) ('%s'). Please " % ex.message + errMsg += "system's temporary directory location(s) ('%s'). Please " % getSafeExString(ex) errMsg += "make sure that there is enough disk space left. If problem persists, " errMsg += "try to set environment variable 'TEMP' to a location " errMsg += "writeable by the current user" @@ -2071,7 +2071,7 @@ def _mergeOptions(inputOptions, overrideOptions): inputOptions = base64unpickle(inputOptions.pickledOptions) except Exception, ex: errMsg = "provided invalid value '%s' for option '--pickled-options'" % inputOptions.pickledOptions - errMsg += " ('%s')" % ex.message if ex.message else "" + errMsg += " ('%s')" % ex if ex.message else "" raise SqlmapSyntaxException(errMsg) if inputOptions.configFile: diff --git a/lib/parse/configfile.py b/lib/parse/configfile.py index dbbc5ad78..d18f87454 100644 --- a/lib/parse/configfile.py +++ b/lib/parse/configfile.py @@ -6,6 +6,7 @@ See the file 'doc/COPYING' for copying permission """ from lib.core.common import checkFile +from lib.core.common import getSafeExString from lib.core.common import getUnicode from lib.core.common import openFile from lib.core.common import unArrayizeValue @@ -67,7 +68,7 @@ def configFileParser(configFile): config = UnicodeRawConfigParser() config.readfp(configFP) except Exception, ex: - errMsg = "you have provided an invalid and/or unreadable configuration file ('%s')" % ex.message + errMsg = "you have provided an invalid and/or unreadable configuration file ('%s')" % getSafeExString(ex) raise SqlmapSyntaxException(errMsg) if not config.has_section("Target"): diff --git a/lib/request/connect.py b/lib/request/connect.py index 76b1afdf8..b5b716bbc 100644 --- a/lib/request/connect.py +++ b/lib/request/connect.py @@ -40,6 +40,7 @@ from lib.core.common import getCurrentThreadData from lib.core.common import getHeader from lib.core.common import getHostHeader from lib.core.common import getRequestHeader +from lib.core.common import getSafeExString from lib.core.common import getUnicode from lib.core.common import logHTTPTraffic from lib.core.common import pushValue @@ -497,22 +498,22 @@ class Connect(object): if hasattr(conn.fp, '_sock'): conn.fp._sock.close() conn.close() - except Exception, msg: - warnMsg = "problem occurred during connection closing ('%s')" % msg + except Exception, ex: + warnMsg = "problem occurred during connection closing ('%s')" % getSafeExString(ex) logger.warn(warnMsg) - except urllib2.HTTPError, e: + except urllib2.HTTPError, ex: page = None responseHeaders = None try: - page = e.read() if not skipRead else None - responseHeaders = e.info() - responseHeaders[URI_HTTP_HEADER] = e.geturl() + page = ex.read() if not skipRead else None + responseHeaders = ex.info() + responseHeaders[URI_HTTP_HEADER] = ex.geturl() page = decodePage(page, responseHeaders.get(HTTP_HEADER.CONTENT_ENCODING), responseHeaders.get(HTTP_HEADER.CONTENT_TYPE)) except socket.timeout: warnMsg = "connection timed out while trying " - warnMsg += "to get error page information (%d)" % e.code + warnMsg += "to get error page information (%d)" % ex.code logger.warn(warnMsg) return None, None, None except KeyboardInterrupt: @@ -522,13 +523,13 @@ class Connect(object): finally: page = page if isinstance(page, unicode) else getUnicode(page) - code = e.code + code = ex.code kb.originalCode = kb.originalCode or code threadData.lastHTTPError = (threadData.lastRequestUID, code) kb.httpErrorCodes[code] = kb.httpErrorCodes.get(code, 0) + 1 - status = getUnicode(e.msg) + status = getUnicode(ex.msg) responseMsg += "[#%d] (%d %s):\n" % (threadData.lastRequestUID, code, status) if responseHeaders: @@ -545,11 +546,11 @@ class Connect(object): logger.log(CUSTOM_LOGGING.TRAFFIC_IN, responseMsg) - if e.code == httplib.UNAUTHORIZED and not conf.ignore401: + if ex.code == httplib.UNAUTHORIZED and not conf.ignore401: errMsg = "not authorized, try to provide right HTTP " errMsg += "authentication type and valid credentials (%d)" % code raise SqlmapConnectionException(errMsg) - elif e.code == httplib.NOT_FOUND: + elif ex.code == httplib.NOT_FOUND: if raise404: errMsg = "page not found (%d)" % code raise SqlmapConnectionException(errMsg) @@ -557,11 +558,11 @@ class Connect(object): debugMsg = "page not found (%d)" % code singleTimeLogMessage(debugMsg, logging.DEBUG) processResponse(page, responseHeaders) - elif e.code == httplib.GATEWAY_TIMEOUT: + elif ex.code == httplib.GATEWAY_TIMEOUT: if ignoreTimeout: return None, None, None else: - warnMsg = "unable to connect to the target URL (%d - %s)" % (e.code, httplib.responses[e.code]) + warnMsg = "unable to connect to the target URL (%d - %s)" % (ex.code, httplib.responses[ex.code]) if threadData.retriesCount < conf.retries and not kb.threadException: warnMsg += ". sqlmap is going to retry the request" logger.critical(warnMsg) @@ -575,7 +576,7 @@ class Connect(object): debugMsg = "got HTTP error code: %d (%s)" % (code, status) logger.debug(debugMsg) - except (urllib2.URLError, socket.error, socket.timeout, httplib.HTTPException, struct.error, ProxyError, SqlmapCompressionException, WebSocketException), e: + except (urllib2.URLError, socket.error, socket.timeout, httplib.HTTPException, struct.error, ProxyError, SqlmapCompressionException, WebSocketException): tbMsg = traceback.format_exc() if "no host given" in tbMsg: @@ -718,7 +719,7 @@ class Connect(object): payload = function(payload=payload, headers=auxHeaders) except Exception, ex: errMsg = "error occurred while running tamper " - errMsg += "function '%s' ('%s')" % (function.func_name, ex) + errMsg += "function '%s' ('%s')" % (function.func_name, getSafeExString(ex)) raise SqlmapGenericException(errMsg) if not isinstance(payload, basestring): diff --git a/lib/request/httpshandler.py b/lib/request/httpshandler.py index 08e6b4193..0ade4aca4 100644 --- a/lib/request/httpshandler.py +++ b/lib/request/httpshandler.py @@ -9,6 +9,7 @@ import httplib import socket import urllib2 +from lib.core.common import getSafeExString from lib.core.data import kb from lib.core.data import logger from lib.core.exception import SqlmapConnectionException @@ -57,7 +58,7 @@ class HTTPSConnection(httplib.HTTPSConnection): sock.close() except (ssl.SSLError, socket.error, httplib.BadStatusLine), ex: self._tunnel_host = None - logger.debug("SSL connection error occurred ('%s')" % ex.message) + logger.debug("SSL connection error occurred ('%s')" % getSafeExString(ex)) # Reference(s): https://docs.python.org/2/library/ssl.html#ssl.SSLContext # https://www.mnot.net/blog/2014/12/27/python_2_and_tls_sni @@ -77,7 +78,7 @@ class HTTPSConnection(httplib.HTTPSConnection): sock.close() except (ssl.SSLError, socket.error, httplib.BadStatusLine), ex: self._tunnel_host = None - logger.debug("SSL connection error occurred ('%s')" % ex.message) + logger.debug("SSL connection error occurred ('%s')" % getSafeExString(ex)) if not success: raise SqlmapConnectionException("can't establish SSL connection") diff --git a/lib/utils/api.py b/lib/utils/api.py index caa46c188..45eb46be8 100644 --- a/lib/utils/api.py +++ b/lib/utils/api.py @@ -17,6 +17,7 @@ import time import urllib2 from lib.core.common import dataToStdout +from lib.core.common import getSafeExString from lib.core.common import unArrayizeValue from lib.core.convert import base64pickle from lib.core.convert import hexencode @@ -87,7 +88,7 @@ class Database(object): else: self.cursor.execute(statement) except sqlite3.OperationalError, ex: - if not "locked" in ex.message: + if not "locked" in getSafeExString(ex): raise else: break diff --git a/lib/utils/google.py b/lib/utils/google.py index 7849befbb..8ee1ba99c 100644 --- a/lib/utils/google.py +++ b/lib/utils/google.py @@ -12,6 +12,7 @@ import socket import urllib import urllib2 +from lib.core.common import getSafeExString from lib.core.common import getUnicode from lib.core.common import readInput from lib.core.common import urlencode @@ -50,7 +51,7 @@ class Google(object): conn = self.opener.open("http://www.google.com/ncr") conn.info() # retrieve session cookie except Exception, ex: - errMsg = "unable to connect to Google ('%s')" % ex.message + errMsg = "unable to connect to Google ('%s')" % getSafeExString(ex) raise SqlmapConnectionException(errMsg) def search(self, dork): diff --git a/lib/utils/hash.py b/lib/utils/hash.py index 81af27026..e0a0a0c50 100644 --- a/lib/utils/hash.py +++ b/lib/utils/hash.py @@ -44,6 +44,7 @@ from lib.core.common import clearConsoleLine from lib.core.common import dataToStdout from lib.core.common import getFileItems from lib.core.common import getPublicTypeMembers +from lib.core.common import getSafeExString from lib.core.common import hashDBRetrieve from lib.core.common import hashDBWrite from lib.core.common import normalizeUnicode @@ -771,7 +772,7 @@ def dictionaryAttack(attack_dict): except Exception, ex: warnMsg = "there was a problem while loading dictionaries" - warnMsg += " ('%s')" % ex.message + warnMsg += " ('%s')" % getSafeExString(ex) logger.critical(warnMsg) message = "do you want to use common password suffixes? (slow!) [y/N] " diff --git a/lib/utils/hashdb.py b/lib/utils/hashdb.py index 3f20432d9..555be564b 100644 --- a/lib/utils/hashdb.py +++ b/lib/utils/hashdb.py @@ -11,6 +11,7 @@ import sqlite3 import threading import time +from lib.core.common import getSafeExString from lib.core.common import getUnicode from lib.core.common import serializeObject from lib.core.common import unserializeObject @@ -77,7 +78,7 @@ class HashDB(object): for row in self.cursor.execute("SELECT value FROM storage WHERE id=?", (hash_,)): retVal = row[0] except sqlite3.OperationalError, ex: - if not "locked" in ex.message: + if not "locked" in getSafeExString(ex): raise except sqlite3.DatabaseError, ex: errMsg = "error occurred while accessing session file '%s' ('%s'). " % (self.filepath, ex) @@ -127,7 +128,7 @@ class HashDB(object): if retries == 0: warnMsg = "there has been a problem while writing to " - warnMsg += "the session file ('%s')" % ex.message + warnMsg += "the session file ('%s')" % getSafeExString(ex) logger.warn(warnMsg) if retries >= HASHDB_FLUSH_RETRIES: diff --git a/plugins/generic/entries.py b/plugins/generic/entries.py index 125aa8226..1d9e770b7 100644 --- a/plugins/generic/entries.py +++ b/plugins/generic/entries.py @@ -12,6 +12,7 @@ from lib.core.bigarray import BigArray from lib.core.common import Backend from lib.core.common import clearConsoleLine from lib.core.common import getLimitRange +from lib.core.common import getSafeExString from lib.core.common import getUnicode from lib.core.common import isInferenceAvailable from lib.core.common import isListLike @@ -341,13 +342,13 @@ class Entries: attackDumpedTable() except (IOError, OSError), ex: errMsg = "an error occurred while attacking " - errMsg += "table dump ('%s')" % ex.message + errMsg += "table dump ('%s')" % getSafeExString(ex) logger.critical(errMsg) conf.dumper.dbTableValues(kb.data.dumpedTable) except SqlmapConnectionException, ex: errMsg = "connection exception detected in dumping phase " - errMsg += "('%s')" % ex.message + errMsg += "('%s')" % getSafeExString(ex) logger.critical(errMsg) finally: diff --git a/sqlmap.py b/sqlmap.py index 6bb12a56f..d7bf52912 100755 --- a/sqlmap.py +++ b/sqlmap.py @@ -25,6 +25,7 @@ from lib.controller.controller import start from lib.core.common import banner from lib.core.common import createGithubIssue from lib.core.common import dataToStdout +from lib.core.common import getSafeExString from lib.core.common import getUnicode from lib.core.common import maskSensitiveData from lib.core.common import setPaths @@ -119,7 +120,7 @@ def main(): cmdLineOptions.sqlmapShell = False except SqlmapBaseException as ex: - errMsg = getUnicode(ex.message) + errMsg = getSafeExString(ex) logger.critical(errMsg) sys.exit(1) diff --git a/tamper/symboliclogical.py b/tamper/symboliclogical.py index cb8e91630..152e028ce 100644 --- a/tamper/symboliclogical.py +++ b/tamper/symboliclogical.py @@ -19,7 +19,7 @@ def tamper(payload, **kwargs): Replaces AND and OR logical operators with their symbolic counterparts (&& and ||) >>> tamper("1 AND '1'='1") - '1 && '1'='1' + "1 %26%26 '1'='1" """ retVal = payload