def checkEnvironment(): try: os.path.isdir(modulePath()) except UnicodeEncodeError: errMsg = "your system does not properly handle non-ASCII paths. " errMsg += "Please move the sqlmap's directory to the other location" logger.critical(errMsg) raise SystemExit if LooseVersion(VERSION) < LooseVersion("1.0"): errMsg = "your runtime environment (e.g. PYTHONPATH) is " errMsg += "broken. Please make sure that you are not running " errMsg += "newer versions of sqlmap with runtime scripts for older " errMsg += "versions" logger.critical(errMsg) raise SystemExit # Patch for pip (import) environment if "sqlmap.sqlmap" in sys.modules: for _ in ("cmdLineOptions", "conf", "kb"): globals()[_] = getattr(sys.modules["lib.core.data"], _) for _ in ("SqlmapBaseException", "SqlmapShellQuitException", "SqlmapSilentQuitException", "SqlmapUserQuitException"): globals()[_] = getattr(sys.modules["lib.core.exception"], _)
def udfSetLocalPaths(self): self.udfLocalFile = paths.SQLMAP_UDF_PATH self.udfSharedLibName = "libs%s" % randomStr(lowercase=True) self.getVersionFromBanner() banVer = kb.bannerFp["dbmsVersion"] if not banVer or not banVer[0].isdigit(): errMsg = "unsupported feature on unknown version of PostgreSQL" raise SqlmapUnsupportedFeatureException(errMsg) elif LooseVersion(banVer) >= LooseVersion("10"): majorVer = banVer.split('.')[0] elif LooseVersion(banVer) >= LooseVersion("8.2") and '.' in banVer: majorVer = '.'.join(banVer.split('.')[:2]) else: errMsg = "unsupported feature on versions of PostgreSQL before 8.2" raise SqlmapUnsupportedFeatureException(errMsg) try: if Backend.isOs(OS.WINDOWS): _ = os.path.join(self.udfLocalFile, "postgresql", "windows", "%d" % Backend.getArch(), majorVer, "lib_postgresqludf_sys.dll_") checkFile(_) self.udfLocalFile = decloakToTemp(_) self.udfSharedLibExt = "dll" else: _ = os.path.join(self.udfLocalFile, "postgresql", "linux", "%d" % Backend.getArch(), majorVer, "lib_postgresqludf_sys.so_") checkFile(_) self.udfLocalFile = decloakToTemp(_) self.udfSharedLibExt = "so" except SqlmapSystemException: errMsg = "unsupported feature on PostgreSQL %s (%s-bit)" % (majorVer, Backend.getArch()) raise SqlmapUnsupportedFeatureException(errMsg)
def udfSetRemotePath(self): self.getVersionFromBanner() banVer = kb.bannerFp["dbmsVersion"] if banVer and LooseVersion(banVer) >= LooseVersion("5.0.67"): if self.__plugindir is None: logger.info("retrieving MySQL plugin directory absolute path") self.__plugindir = unArrayizeValue( inject.getValue("SELECT @@plugin_dir")) # On MySQL 5.1 >= 5.1.19 and on any version of MySQL 6.0 if self.__plugindir is None and LooseVersion( banVer) >= LooseVersion("5.1.19"): logger.info("retrieving MySQL base directory absolute path") # Reference: http://dev.mysql.com/doc/refman/5.1/en/server-options.html#option_mysqld_basedir self.__basedir = unArrayizeValue( inject.getValue("SELECT @@basedir")) if isWindowsDriveLetterPath(self.__basedir or ""): Backend.setOs(OS.WINDOWS) else: Backend.setOs(OS.LINUX) # The DLL must be in C:\Program Files\MySQL\MySQL Server 5.1\lib\plugin if Backend.isOs(OS.WINDOWS): self.__plugindir = "%s/lib/plugin" % self.__basedir else: self.__plugindir = "%s/lib/mysql/plugin" % self.__basedir self.__plugindir = ntToPosixSlashes(normalizePath( self.__plugindir)) or '.' self.udfRemoteFile = "%s/%s.%s" % ( self.__plugindir, self.udfSharedLibName, self.udfSharedLibExt) # On MySQL 4.1 < 4.1.25 and on MySQL 4.1 >= 4.1.25 with NO plugin_dir set in my.ini configuration file # On MySQL 5.0 < 5.0.67 and on MySQL 5.0 >= 5.0.67 with NO plugin_dir set in my.ini configuration file else: # logger.debug("retrieving MySQL data directory absolute path") # Reference: http://dev.mysql.com/doc/refman/5.1/en/server-options.html#option_mysqld_datadir # self.__datadir = inject.getValue("SELECT @@datadir") # NOTE: specifying the relative path as './udf.dll' # saves in @@datadir on both MySQL 4.1 and MySQL 5.0 self.__datadir = '.' self.__datadir = ntToPosixSlashes(normalizePath(self.__datadir)) # The DLL can be in either C:\WINDOWS, C:\WINDOWS\system, # C:\WINDOWS\system32, @@basedir\bin or @@datadir self.udfRemoteFile = "%s/%s.%s" % ( self.__datadir, self.udfSharedLibName, self.udfSharedLibExt)
def connect(self): def create_sock(): sock = socket.create_connection((self.host, self.port), self.timeout) if getattr(self, "_tunnel_host", None): self.sock = sock self._tunnel() return sock success = False # Reference(s): https://docs.python.org/2/library/ssl.html#ssl.SSLContext # https://www.mnot.net/blog/2014/12/27/python_2_and_tls_sni if re.search(r"\A[\d.]+\Z", conf.hostname or "") is None and kb.tlsSNI.get(conf.hostname) is not False and hasattr(ssl, "SSLContext"): for protocol in (_ for _ in _protocols if _ >= ssl.PROTOCOL_TLSv1): try: sock = create_sock() if protocol not in _contexts: _contexts[protocol] = ssl.SSLContext(protocol) try: # Reference(s): https://askubuntu.com/a/1263098 # https://askubuntu.com/a/1250807 _contexts[protocol].set_ciphers("DEFAULT@SECLEVEL=1") except ssl.SSLError: pass result = _contexts[protocol].wrap_socket(sock, do_handshake_on_connect=True, server_hostname=conf.hostname) if result: success = True self.sock = result _protocols.remove(protocol) _protocols.insert(0, protocol) break else: sock.close() except (ssl.SSLError, socket.error, _http_client.BadStatusLine) as ex: self._tunnel_host = None logger.debug("SSL connection error occurred for '%s' ('%s')" % (_lut[protocol], getSafeExString(ex))) if kb.tlsSNI.get(conf.hostname) is None: kb.tlsSNI[conf.hostname] = success if not success: for protocol in _protocols: try: sock = create_sock() _ = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version=protocol) if _: success = True self.sock = _ _protocols.remove(protocol) _protocols.insert(0, protocol) break else: sock.close() except (ssl.SSLError, socket.error, _http_client.BadStatusLine) as ex: self._tunnel_host = None logger.debug("SSL connection error occurred for '%s' ('%s')" % (_lut[protocol], getSafeExString(ex))) if not success: errMsg = "can't establish SSL connection" # Reference: https://docs.python.org/2/library/ssl.html if LooseVersion(PYVERSION) < LooseVersion("2.7.9"): errMsg += " (please retry with Python >= 2.7.9)" if kb.sslSuccess and not self.retrying: self.retrying = True for _ in xrange(conf.retries): try: self.connect() except SqlmapConnectionException: pass else: return raise SqlmapConnectionException(errMsg) else: kb.sslSuccess = True