Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cf8e926

Browse files
committed
changes regarding EXISTS feature
1 parent 51beafc commit cf8e926

6 files changed

Lines changed: 120 additions & 21 deletions

File tree

lib/controller/action.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from lib.core.common import dataToStdout
2828
from lib.core.data import conf
2929
from lib.core.data import kb
30+
from lib.core.data import paths
3031
from lib.core.exception import sqlmapUnsupportedDBMSException
3132
from lib.core.settings import SUPPORTED_DBMS
3233
from lib.techniques.blind.timebased import timeTest
@@ -111,6 +112,12 @@ def action():
111112
if conf.getTables:
112113
conf.dumper.dbTables(conf.dbmsHandler.getTables())
113114

115+
if conf.cExists:
116+
conf.dumper.dbTables(conf.dbmsHandler.tableExists(paths.COMMON_TABLES))
117+
118+
if conf.tableFile:
119+
conf.dumper.dbTables(conf.dbmsHandler.tableExists(conf.tableFile))
120+
114121
if conf.getColumns:
115122
conf.dumper.dbTableColumns(conf.dbmsHandler.getColumns())
116123

lib/core/common.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,8 @@ def filePathToString(filePath):
411411

412412
return strRepl
413413

414-
def dataToStdout(data):
415-
if conf.verbose > 0:
414+
def dataToStdout(data, forceOutput=False):
415+
if conf.verbose > 0 or forceOutput:
416416
try:
417417
sys.stdout.write(data)
418418
sys.stdout.flush()
@@ -657,6 +657,8 @@ def setPaths():
657657
# sqlmap files
658658
paths.SQLMAP_HISTORY = os.path.join(paths.SQLMAP_ROOT_PATH, ".sqlmap_history")
659659
paths.SQLMAP_CONFIG = os.path.join(paths.SQLMAP_ROOT_PATH, "sqlmap-%s.conf" % randomStr())
660+
paths.COMMON_OUTPUTS = os.path.join(paths.SQLMAP_TXT_PATH, 'common-outputs.txt')
661+
paths.COMMON_TABLES = os.path.join(paths.SQLMAP_TXT_PATH, "common-tables.txt")
660662
paths.FUZZ_VECTORS = os.path.join(paths.SQLMAP_TXT_PATH, "fuzz_vectors.txt")
661663
paths.DETECTION_RULES_XML = os.path.join(paths.SQLMAP_XML_PATH, "detection.xml")
662664
paths.ERRORS_XML = os.path.join(paths.SQLMAP_XML_PATH, "errors.xml")
@@ -1233,8 +1235,7 @@ def initCommonOutputs():
12331235
kb.commonOutputs = {}
12341236
key = None
12351237

1236-
fileName = os.path.join(paths.SQLMAP_TXT_PATH, 'common-outputs.txt')
1237-
cfile = codecs.open(fileName, 'r', conf.dataEncoding)
1238+
cfile = codecs.open(paths.COMMON_OUTPUTS, 'r', conf.dataEncoding)
12381239

12391240
for line in cfile.readlines(): # xreadlines doesn't return unicode strings when codec.open() is used
12401241
if line.find('#') != -1:
@@ -1254,6 +1255,21 @@ def initCommonOutputs():
12541255

12551256
cfile.close()
12561257

1258+
def getFileItems(filename):
1259+
retVal = []
1260+
1261+
checkFile(filename)
1262+
file = codecs.open(filename, 'r', conf.dataEncoding)
1263+
1264+
for line in file.readlines(): # xreadlines doesn't return unicode strings when codec.open() is used
1265+
if line.find('#') != -1:
1266+
line = line[:line.find('#')]
1267+
line = line.strip()
1268+
if line:
1269+
retVal.append(line)
1270+
1271+
return retVal
1272+
12571273
def goGoodSamaritan(prevValue, originalCharset):
12581274
"""
12591275
Function for retrieving parameters needed for common prediction (good
@@ -1411,4 +1427,10 @@ def replaceSpaces(query):
14111427
if query:
14121428
return query if conf.space is None else query.replace(' ', conf.space)
14131429
else:
1414-
return query
1430+
return query
1431+
1432+
def pushValue(value):
1433+
kb.valueStack.append(value)
1434+
1435+
def popValue():
1436+
return kb.valueStack.pop()

lib/core/dump.py

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -157,37 +157,58 @@ def dbs(self,dbs):
157157
self.lister("available databases", dbs)
158158

159159
def dbTables(self, dbTables):
160-
if not isinstance(dbTables, dict):
161-
self.string("tables", dbTables)
162-
163-
return
160+
if isinstance(dbTables, list):
161+
maxlength = 0
164162

165-
maxlength = 0
166-
167-
for tables in dbTables.values():
168-
for table in tables:
163+
for table in dbTables:
169164
maxlength = max(maxlength, len(table))
170165

171-
lines = "-" * (int(maxlength) + 2)
172-
173-
for db, tables in dbTables.items():
174-
tables.sort(key=lambda x: x.lower())
166+
lines = "-" * (int(maxlength) + 2)
175167

176-
self.__write("Database: %s" % db)
168+
dbTables.sort(key=lambda x: x.lower())
177169

178-
if len(tables) == 1:
170+
if len(dbTables) == 1:
179171
self.__write("[1 table]")
180172
else:
181-
self.__write("[%d tables]" % len(tables))
173+
self.__write("[%d tables]" % len(dbTables))
182174

183175
self.__write("+%s+" % lines)
184176

185-
for table in tables:
177+
for table in dbTables:
186178
blank = " " * (maxlength - len(table))
187179
self.__write("| %s%s |" % (table, blank))
188180

189181
self.__write("+%s+\n" % lines)
190182

183+
elif isinstance(dbTables, dict):
184+
maxlength = 0
185+
186+
for tables in dbTables.values():
187+
for table in tables:
188+
maxlength = max(maxlength, len(table))
189+
190+
lines = "-" * (int(maxlength) + 2)
191+
192+
for db, tables in dbTables.items():
193+
tables.sort(key=lambda x: x.lower())
194+
195+
self.__write("Database: %s" % db)
196+
197+
if len(tables) == 1:
198+
self.__write("[1 table]")
199+
else:
200+
self.__write("[%d tables]" % len(tables))
201+
202+
self.__write("+%s+" % lines)
203+
204+
for table in tables:
205+
blank = " " * (maxlength - len(table))
206+
self.__write("| %s%s |" % (table, blank))
207+
208+
self.__write("+%s+\n" % lines)
209+
else:
210+
self.string("tables", dbTables)
211+
191212
def dbTableColumns(self, tableColumns):
192213
for db, tables in tableColumns.items():
193214
if not db:

lib/core/option.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,7 @@ def __setKnowledgeBaseAttributes():
10311031
kb.unionPosition = None
10321032
kb.unionNegative = False
10331033
kb.unionFalseCond = False
1034+
kb.valueStack = []
10341035

10351036
def __saveCmdline():
10361037
"""

lib/parse/cmdline.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,12 @@ def cmdLineParser():
332332
action="store_true", default=False,
333333
help="Prompt for an interactive SQL shell")
334334

335+
enumeration.add_option("--common-exists", dest="cExists", action="store_true",
336+
default=False, help="Check existence of common tables")
337+
338+
enumeration.add_option("--exists", dest="tableFile",
339+
help="Check existence of user specified tables")
340+
335341
# User-defined function options
336342
udf = OptionGroup(parser, "User-defined function injection", "These "
337343
"options can be used to create custom user-defined "

plugins/generic/enumeration.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,18 @@
2323
"""
2424

2525
import re
26+
import time
2627

2728
from lib.core.agent import agent
29+
from lib.core.common import dataToStdout
2830
from lib.core.common import getRange
2931
from lib.core.common import getCompiledRegex
32+
from lib.core.common import getConsoleWidth
33+
from lib.core.common import getFileItems
3034
from lib.core.common import getUnicode
3135
from lib.core.common import parsePasswordHash
36+
from lib.core.common import popValue
37+
from lib.core.common import pushValue
3238
from lib.core.common import readInput
3339
from lib.core.common import safeStringFormat
3440
from lib.core.convert import urlencode
@@ -47,6 +53,7 @@
4753
from lib.core.unescaper import unescaper
4854
from lib.parse.banner import bannerParser
4955
from lib.request import inject
56+
from lib.request.connect import Connect as Request
5057
from lib.techniques.inband.union.test import unionTest
5158
from lib.techniques.outband.stacked import stackedTest
5259

@@ -801,6 +808,41 @@ def getTables(self):
801808

802809
return kb.data.cachedTables
803810

811+
def tableExists(self, tableFile):
812+
tables = getFileItems(tableFile)
813+
retVal = []
814+
infoMsg = "checking tables existence using items from '%s'" % tableFile
815+
logger.info(infoMsg)
816+
817+
pushValue(conf.verbose)
818+
conf.verbose = 0
819+
count = 0
820+
length = len(tables)
821+
822+
for table in tables:
823+
query = agent.prefixQuery(" %s" % safeStringFormat("AND EXISTS(SELECT 1 FROM %s)", table))
824+
query = agent.postfixQuery(query)
825+
result = Request.queryPage(urlencode(agent.payload(newValue=query)))
826+
827+
if result:
828+
infoMsg = "\r[%s] [INFO] retrieved: %s" % (time.strftime("%X"), table)
829+
infoMsg = "%s%s\n" % (infoMsg, " "*(getConsoleWidth()-1-len(infoMsg)))
830+
dataToStdout(infoMsg, True)
831+
retVal.append(table)
832+
833+
count += 1
834+
status = '%d/%d (%d%s)' % (count, length, round(100.0*count/length), '%')
835+
dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status), True)
836+
837+
conf.verbose = popValue()
838+
839+
dataToStdout("\r%s\n" % (" "*(getConsoleWidth()-1)), True)
840+
if not retVal:
841+
warnMsg = "no table found"
842+
logger.warn(warnMsg)
843+
844+
return retVal
845+
804846
def getColumns(self, onlyColNames=False):
805847
if kb.dbms == "MySQL" and not kb.data.has_information_schema:
806848
errMsg = "information_schema not available, "

0 commit comments

Comments
 (0)