Skip to content

Commit d0dff82

Browse files
committed
Minor code refactoring relating set/get back-end DBMS operating system and minor bug fix to properly enforce OS value with --os switch
1 parent 75142b3 commit d0dff82

20 files changed

Lines changed: 125 additions & 92 deletions

File tree

lib/core/common.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
from extra.magic import magic
4343
from extra.odict.odict import OrderedDict
4444
from lib.core.data import conf
45-
from lib.core.data import dbmsDict
4645
from lib.core.data import kb
4746
from lib.core.data import logger
4847
from lib.core.data import paths
@@ -52,6 +51,7 @@
5251
from lib.core.convert import urlencode
5352
from lib.core.enums import DBMS
5453
from lib.core.enums import HTTPHEADER
54+
from lib.core.enums import OS
5555
from lib.core.enums import PLACE
5656
from lib.core.enums import PAYLOAD
5757
from lib.core.enums import SORTORDER
@@ -64,6 +64,7 @@
6464
from lib.core.optiondict import optDict
6565
from lib.core.settings import INFERENCE_UNKNOWN_CHAR
6666
from lib.core.settings import UNICODE_ENCODING
67+
from lib.core.settings import DBMS_DICT
6768
from lib.core.settings import DESCRIPTION
6869
from lib.core.settings import IS_WIN
6970
from lib.core.settings import PLATFORM
@@ -93,6 +94,7 @@
9394
from lib.core.settings import TIME_STDEV_COEFF
9495
from lib.core.settings import DYNAMICITY_MARK_LENGTH
9596
from lib.core.settings import SENSITIVE_DATA_REGEX
97+
from lib.core.settings import SUPPORTED_OS
9698
from lib.core.settings import UNKNOWN_DBMS_VERSION
9799
from lib.core.settings import URI_INJECTION_MARK_CHAR
98100
from lib.core.settings import URI_QUESTION_MARKER
@@ -305,7 +307,7 @@ def setOs(os):
305307
return None
306308

307309
# Little precaution, in theory this condition should always be false
308-
elif kb.os is not None and kb.os != os:
310+
elif kb.os is not None and isinstance(os, basestring) and kb.os.lower() != os.lower():
309311
msg = "sqlmap previously fingerprinted back-end DBMS "
310312
msg += "operating system %s. However now it has " % kb.os
311313
msg += "been fingerprinted to be %s. " % os
@@ -318,14 +320,14 @@ def setOs(os):
318320
if inp == kb.os:
319321
break
320322
elif inp == os:
321-
kb.os = inp
323+
kb.os = inp.capitalize()
322324
break
323325
else:
324326
warnMsg = "invalid value"
325327
logger.warn(warnMsg)
326328

327-
elif kb.os is None:
328-
kb.os = os
329+
elif kb.os is None and isinstance(os, basestring):
330+
kb.os = os.capitalize()
329331

330332
return kb.os
331333

@@ -419,7 +421,7 @@ def isVersionGreaterOrEqualThan(version):
419421

420422
@staticmethod
421423
def isOs(os):
422-
return Backend.getOs() is not None and Backend.getOs().lower() == kb.os.lower()
424+
return Backend.getOs() is not None and Backend.getOs().lower() == os.lower()
423425

424426
def paramToDict(place, parameters=None):
425427
"""
@@ -506,7 +508,7 @@ def getDocRoot():
506508
docRoot = None
507509
pagePath = directoryPath(conf.path)
508510

509-
if kb.os == "Windows":
511+
if Backend.isOs(OS.WINDOWS):
510512
defaultDocRoot = ["C:/xampp/htdocs/", "C:/Inetpub/wwwroot/"]
511513
else:
512514
defaultDocRoot = ["/var/www/"]
@@ -954,7 +956,7 @@ def parseTargetDirect():
954956
errMsg += "or 'access://DATABASE_FILEPATH'"
955957
raise sqlmapSyntaxException, errMsg
956958

957-
for dbmsName, data in dbmsDict.items():
959+
for dbmsName, data in DBMS_DICT.items():
958960
if conf.dbms in data[0]:
959961
try:
960962
if dbmsName in (DBMS.ACCESS, DBMS.SQLITE, DBMS.FIREBIRD):
@@ -2064,7 +2066,7 @@ def aliasToDbmsEnum(dbms):
20642066
if dbms is None:
20652067
return None
20662068

2067-
for key, item in dbmsDict.items():
2069+
for key, item in DBMS_DICT.items():
20682070
if dbms.lower() in item[0]:
20692071
retVal = key
20702072
break

lib/core/data.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,3 @@
3838

3939
# logger
4040
logger = LOGGER
41-
42-
dbmsDict = { DBMS.MSSQL: [MSSQL_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/"],
43-
DBMS.MYSQL: [MYSQL_ALIASES, "python-mysqldb", "http://mysql-python.sourceforge.net/"],
44-
DBMS.PGSQL: [PGSQL_ALIASES, "python-psycopg2", "http://initd.org/psycopg/"],
45-
DBMS.ORACLE: [ORACLE_ALIASES, "python cx_Oracle", "http://cx-oracle.sourceforge.net/"],
46-
DBMS.SQLITE: [SQLITE_ALIASES, "python-pysqlite2", "http://pysqlite.googlecode.com/"],
47-
DBMS.ACCESS: [ACCESS_ALIASES, "python-pyodbc", "http://pyodbc.googlecode.com/"],
48-
DBMS.FIREBIRD: [FIREBIRD_ALIASES, "python-kinterbasdb", "http://kinterbasdb.sourceforge.net/"],
49-
DBMS.MAXDB: [MAXDB_ALIASES, None, None],
50-
DBMS.SYBASE: [SYBASE_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/"]
51-
}

lib/core/enums.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ class DBMS:
3535
SQLITE = "SQLite"
3636
SYBASE = "Sybase"
3737

38+
class OS:
39+
LINUX = "Linux"
40+
WINDOWS = "Windows"
41+
3842
class PLACE:
3943
GET = "GET"
4044
POST = "POST"

lib/core/option.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
from lib.core.settings import PYVERSION
7676
from lib.core.settings import SITE
7777
from lib.core.settings import DEFAULT_TOR_PROXY
78+
from lib.core.settings import DBMS_DICT
7879
from lib.core.settings import SUPPORTED_DBMS
7980
from lib.core.settings import SUPPORTED_OS
8081
from lib.core.settings import VERSION_STRING
@@ -601,20 +602,21 @@ def __setOS():
601602
if not conf.os:
602603
return
603604

604-
debugMsg = "forcing back-end DBMS operating system to user defined value"
605-
logger.debug(debugMsg)
606-
607-
conf.os = conf.os.lower()
608-
609-
if conf.os not in SUPPORTED_OS:
610-
errMsg = "you provided an unsupported back-end DBMS operating "
605+
if conf.os.lower() not in SUPPORTED_OS:
606+
errMsg = "you provided an unsupported back-end DBMS operating "
611607
errMsg += "system. The supported DBMS operating systems for OS "
612-
errMsg += "and file system access are Linux and Windows. "
608+
errMsg += "and file system access are %s. " % ', '.join([o.capitalize() for o in SUPPORTED_OS])
613609
errMsg += "If you do not know the back-end DBMS underlying OS, "
614610
errMsg += "do not provide it and sqlmap will fingerprint it for "
615611
errMsg += "you."
616612
raise sqlmapUnsupportedDBMSException, errMsg
617613

614+
debugMsg = "forcing back-end DBMS operating system to user defined "
615+
debugMsg += "value '%s'" % conf.os
616+
logger.debug(debugMsg)
617+
618+
Backend.setOs(conf.os)
619+
618620
def __setTechnique():
619621
validTechniques = sorted(getPublicTypeMembers(PAYLOAD.TECHNIQUE), key=lambda x: x[1])
620622
validLetters = map(lambda x: x[0][0].upper(), validTechniques)
@@ -667,11 +669,10 @@ def __setDBMS():
667669
Backend.setVersion(str(dbmsRegExp.group(2)))
668670

669671
if conf.dbms not in SUPPORTED_DBMS:
670-
errMsg = "you provided an unsupported back-end database management "
671-
errMsg += "system. The supported DBMS are MySQL, PostgreSQL, "
672-
errMsg += "Microsoft SQL Server and Oracle. If you do not know "
673-
errMsg += "the back-end DBMS, do not provide it and sqlmap will "
674-
errMsg += "fingerprint it for you."
672+
errMsg = "you provided an unsupported back-end database management "
673+
errMsg += "system. The supported DBMS are %s. " % ', '.join([d for d in DBMS_DICT])
674+
errMsg += "If you do not know the back-end DBMS, do not provide "
675+
errMsg += "it and sqlmap will fingerprint it for you."
675676
raise sqlmapUnsupportedDBMSException, errMsg
676677

677678
for aliases in (MSSQL_ALIASES, MYSQL_ALIASES, PGSQL_ALIASES, \
@@ -1203,6 +1204,12 @@ def __cleanupOptions():
12031204
if conf.data:
12041205
conf.data = urldecode(conf.data)
12051206

1207+
if conf.os:
1208+
conf.os = conf.os.capitalize()
1209+
1210+
if conf.dbms:
1211+
conf.dbms = conf.dbms.capitalize()
1212+
12061213
# to distinguish explicit usage of --time-sec
12071214
if conf.timeSec is None:
12081215
if conf.tor:

lib/core/session.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from lib.core.data import logger
2323
from lib.core.datatype import injectionDict
2424
from lib.core.enums import DBMS
25+
from lib.core.enums import OS
2526
from lib.core.enums import PAYLOAD
2627
from lib.core.enums import PLACE
2728
from lib.core.settings import METADB_SUFFIX
@@ -123,8 +124,8 @@ def setOs():
123124
return
124125

125126
if "type" in kb.bannerFp:
126-
kb.os = Format.humanize(kb.bannerFp["type"])
127-
infoMsg = "the back-end DBMS operating system is %s" % kb.os
127+
Backend.setOs(Format.humanize(kb.bannerFp["type"]))
128+
infoMsg = "the back-end DBMS operating system is %s" % Backend.getOs()
128129

129130
if "distrib" in kb.bannerFp:
130131
kb.osVersion = Format.humanize(kb.bannerFp["distrib"])
@@ -133,17 +134,17 @@ def setOs():
133134
if "sp" in kb.bannerFp:
134135
kb.osSP = int(Format.humanize(kb.bannerFp["sp"]).replace("Service Pack ", ""))
135136

136-
elif "sp" not in kb.bannerFp and kb.os == "Windows":
137+
elif "sp" not in kb.bannerFp and Backend.isOs(OS.WINDOWS):
137138
kb.osSP = 0
138139

139-
if kb.os and kb.osVersion and kb.osSP:
140+
if Backend.getOs() and kb.osVersion and kb.osSP:
140141
infoMsg += " Service Pack %d" % kb.osSP
141142

142143
if infoMsg:
143144
logger.info(infoMsg)
144145

145146
if condition:
146-
dataToSessionFile("[%s][%s][%s][OS][%s]\n" % (conf.url, kb.injection.place, safeFormatString(conf.parameters[kb.injection.place]), safeFormatString(kb.os)))
147+
dataToSessionFile("[%s][%s][%s][OS][%s]\n" % (conf.url, kb.injection.place, safeFormatString(conf.parameters[kb.injection.place]), Backend.getOs()))
147148

148149
def setRemoteTempPath():
149150
condition = (
@@ -242,6 +243,8 @@ def resumeConfKb(expression, url, value):
242243
else:
243244
conf.os = os
244245

246+
Backend.setOs(conf.os)
247+
245248
elif expression == "Remote temp path" and url == conf.url and conf.tmpPath is None:
246249
conf.tmpPath = unSafeFormatString(value[:-1])
247250

lib/core/settings.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,17 @@
161161
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES
162162
SUPPORTED_OS = ( "linux", "windows" )
163163

164+
DBMS_DICT = { DBMS.MSSQL: [MSSQL_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/"],
165+
DBMS.MYSQL: [MYSQL_ALIASES, "python-mysqldb", "http://mysql-python.sourceforge.net/"],
166+
DBMS.PGSQL: [PGSQL_ALIASES, "python-psycopg2", "http://initd.org/psycopg/"],
167+
DBMS.ORACLE: [ORACLE_ALIASES, "python cx_Oracle", "http://cx-oracle.sourceforge.net/"],
168+
DBMS.SQLITE: [SQLITE_ALIASES, "python-pysqlite2", "http://pysqlite.googlecode.com/"],
169+
DBMS.ACCESS: [ACCESS_ALIASES, "python-pyodbc", "http://pyodbc.googlecode.com/"],
170+
DBMS.FIREBIRD: [FIREBIRD_ALIASES, "python-kinterbasdb", "http://kinterbasdb.sourceforge.net/"],
171+
DBMS.MAXDB: [MAXDB_ALIASES, None, None],
172+
DBMS.SYBASE: [SYBASE_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/"]
173+
}
174+
164175
REFERER_ALIASES = ( "ref", "referer", "referrer" )
165176
USER_AGENT_ALIASES = ( "ua", "useragent", "user-agent" )
166177

lib/core/shell.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from lib.core.data import logger
1818
from lib.core.data import paths
1919
from lib.core.data import queries
20+
from lib.core.enums import OS
2021

2122
def saveHistory():
2223
historyPath = os.path.expanduser(paths.SQLMAP_HISTORY)
@@ -68,7 +69,7 @@ def autoCompletion(sqlShell=False, osShell=False):
6869
if sqlShell:
6970
completer = CompleterNG(queriesForAutoCompletion())
7071
elif osShell:
71-
if kb.os == "Windows":
72+
if Backend.isOs(OS.WINDOWS):
7273
# Reference: http://en.wikipedia.org/wiki/List_of_DOS_commands
7374
completer = CompleterNG({
7475
"copy": None, "del": None, "dir": None,

lib/takeover/abstraction.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from lib.core.data import kb
1616
from lib.core.data import logger
1717
from lib.core.enums import DBMS
18+
from lib.core.enums import OS
1819
from lib.core.enums import PAYLOAD
1920
from lib.core.exception import sqlmapUnsupportedFeatureException
2021
from lib.core.shell import autoCompletion
@@ -108,7 +109,7 @@ def shell(self):
108109
errMsg = "feature not yet implemented for the back-end DBMS"
109110
raise sqlmapUnsupportedFeatureException, errMsg
110111

111-
infoMsg = "calling %s OS shell. To quit type " % (kb.os or "Windows")
112+
infoMsg = "calling %s OS shell. To quit type " % (Backend.getOs() or "Windows")
112113
infoMsg += "'x' or 'q' and press ENTER"
113114
logger.info(infoMsg)
114115

lib/takeover/metasploit.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
from lib.core.data import kb
3333
from lib.core.data import logger
3434
from lib.core.enums import DBMS
35+
from lib.core.enums import OS
3536
from lib.core.exception import sqlmapDataException
3637
from lib.core.exception import sqlmapFilePathException
3738
from lib.core.settings import UNICODE_ENCODING
@@ -118,7 +119,7 @@ def __initVars(self):
118119
}
119120

120121
def __skeletonSelection(self, msg, lst=None, maxValue=1, default=1):
121-
if kb.os == "Windows":
122+
if Backend.isOs(OS.WINDOWS):
122123
opSys = "windows"
123124
else:
124125
opSys = "linux"
@@ -169,11 +170,11 @@ def __selectEncoder(self, encode=True):
169170
if isinstance(encode, basestring):
170171
return encode
171172

172-
elif kb.os == "Windows" and encode:
173+
elif Backend.isOs(OS.WINDOWS) and encode:
173174
return self.__skeletonSelection("payload encoding", self.__msfEncodersList)
174175

175176
def __selectPayload(self):
176-
if kb.os == "Windows" and conf.privEsc:
177+
if Backend.isOs(OS.WINDOWS) and conf.privEsc:
177178
infoMsg = "forcing Metasploit payload to Meterpreter because "
178179
infoMsg += "it is the only payload that can be used to "
179180
infoMsg += "escalate privileges, either via 'incognito' "
@@ -358,7 +359,7 @@ def __forgeMsfPayloadCmd(self, exitfunc, format, outFile, extra=None):
358359
elif not self.connectionStr.startswith("bind"):
359360
raise sqlmapDataException, "unexpected connection type"
360361

361-
if kb.os == "Windows" or extra == "BufferRegister=EAX":
362+
if Backend.isOs(OS.WINDOWS) or extra == "BufferRegister=EAX":
362363
self.__payloadCmd += " R | %s -a x86 -e %s -o %s -t %s" % (self.__msfEncode, self.encoderStr, outFile, format)
363364

364365
if extra is not None:
@@ -395,15 +396,15 @@ def __runMsfPayloadRemote(self):
395396
infoMsg += "remotely, please wait.."
396397
logger.info(infoMsg)
397398

398-
if kb.os != "Windows":
399+
if not Backend.isOs(OS.WINDOWS):
399400
self.execCmd("chmod +x %s" % self.exeFilePathRemote, silent=True)
400401

401402
cmd = "%s &" % self.exeFilePathRemote
402403

403404
self.execCmd(cmd, silent=True)
404405

405406
def __loadMetExtensions(self, proc, metSess):
406-
if kb.os != "Windows":
407+
if not Backend.isOs(OS.WINDOWS):
407408
return
408409

409410
if self.resourceFile is not None:
@@ -479,7 +480,7 @@ def __controlMsfCmd(self, proc, func):
479480
func()
480481

481482
if "Starting the payload handler" in out and "shell" in self.payloadStr:
482-
if kb.os == "Windows":
483+
if Backend.isOs(OS.WINDOWS):
483484
proc.stdin.write("whoami\n")
484485
else:
485486
proc.stdin.write("uname -a ; id\n")
@@ -512,7 +513,7 @@ def createMsfShellcode(self, exitfunc, format, extra, encode):
512513
pollProcess(process)
513514
payloadStderr = process.communicate()[1]
514515

515-
if kb.os == "Windows" or extra == "BufferRegister=EAX":
516+
if Backend.isOs(OS.WINDOWS) or extra == "BufferRegister=EAX":
516517
payloadSize = re.search("size ([\d]+)", payloadStderr, re.I)
517518
else:
518519
payloadSize = re.search("Length\:\s([\d]+)", payloadStderr, re.I)
@@ -547,7 +548,7 @@ def createMsfPayloadStager(self, initialize=True):
547548

548549
self.__randStr = randomStr(lowercase=True)
549550

550-
if kb.os == "Windows":
551+
if Backend.isOs(OS.WINDOWS):
551552
self.exeFilePathLocal = os.path.join(conf.outputPath, "tmpm%s.exe" % self.__randStr)
552553

553554
# Metasploit developers added support for the old exe format
@@ -579,7 +580,7 @@ def createMsfPayloadStager(self, initialize=True):
579580
pollProcess(process)
580581
payloadStderr = process.communicate()[1]
581582

582-
if kb.os == "Windows":
583+
if Backend.isOs(OS.WINDOWS):
583584
payloadSize = re.search("size\s([\d]+)", payloadStderr, re.I)
584585
else:
585586
payloadSize = re.search("Length\:\s([\d]+)", payloadStderr, re.I)

0 commit comments

Comments
 (0)