Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sqlmapproject
GitHub Repository: sqlmapproject/sqlmap
Path: blob/master/plugins/generic/search.py
2989 views
1
#!/usr/bin/env python
2
3
"""
4
Copyright (c) 2006-2025 sqlmap developers (https://sqlmap.org)
5
See the file 'LICENSE' for copying permission
6
"""
7
8
import re
9
10
from lib.core.agent import agent
11
from lib.core.common import arrayizeValue
12
from lib.core.common import Backend
13
from lib.core.common import filterPairValues
14
from lib.core.common import getLimitRange
15
from lib.core.common import isInferenceAvailable
16
from lib.core.common import isNoneValue
17
from lib.core.common import isNumPosStrValue
18
from lib.core.common import isTechniqueAvailable
19
from lib.core.common import readInput
20
from lib.core.common import safeSQLIdentificatorNaming
21
from lib.core.common import safeStringFormat
22
from lib.core.common import unArrayizeValue
23
from lib.core.common import unsafeSQLIdentificatorNaming
24
from lib.core.data import conf
25
from lib.core.data import kb
26
from lib.core.data import logger
27
from lib.core.data import paths
28
from lib.core.data import queries
29
from lib.core.enums import CHARSET_TYPE
30
from lib.core.enums import DBMS
31
from lib.core.enums import EXPECTED
32
from lib.core.enums import PAYLOAD
33
from lib.core.exception import SqlmapMissingMandatoryOptionException
34
from lib.core.exception import SqlmapUserQuitException
35
from lib.core.settings import CURRENT_DB
36
from lib.core.settings import METADB_SUFFIX
37
from lib.core.settings import UPPER_CASE_DBMSES
38
from lib.request import inject
39
from lib.utils.brute import columnExists
40
from lib.utils.brute import tableExists
41
from thirdparty import six
42
43
class Search(object):
44
"""
45
This class defines search functionalities for plugins.
46
"""
47
48
def __init__(self):
49
pass
50
51
def searchDb(self):
52
foundDbs = []
53
rootQuery = queries[Backend.getIdentifiedDbms()].search_db
54
dbList = conf.db.split(',')
55
56
if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:
57
dbCond = rootQuery.inband.condition2
58
else:
59
dbCond = rootQuery.inband.condition
60
61
dbConsider, dbCondParam = self.likeOrExact("database")
62
63
for db in dbList:
64
values = []
65
db = safeSQLIdentificatorNaming(db)
66
67
if Backend.getIdentifiedDbms() in UPPER_CASE_DBMSES:
68
db = db.upper()
69
70
infoMsg = "searching database"
71
if dbConsider == "1":
72
infoMsg += "s LIKE"
73
infoMsg += " '%s'" % unsafeSQLIdentificatorNaming(db)
74
logger.info(infoMsg)
75
76
if conf.excludeSysDbs:
77
exclDbsQuery = "".join(" AND '%s' != %s" % (unsafeSQLIdentificatorNaming(db), dbCond) for db in self.excludeDbsList)
78
infoMsg = "skipping system database%s '%s'" % ("s" if len(self.excludeDbsList) > 1 else "", ", ".join(db for db in self.excludeDbsList))
79
logger.info(infoMsg)
80
else:
81
exclDbsQuery = ""
82
83
dbQuery = "%s%s" % (dbCond, dbCondParam)
84
dbQuery = dbQuery % unsafeSQLIdentificatorNaming(db)
85
86
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
87
if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:
88
query = rootQuery.inband.query2
89
else:
90
query = rootQuery.inband.query
91
92
query = query % (dbQuery + exclDbsQuery)
93
values = inject.getValue(query, blind=False, time=False)
94
95
if not isNoneValue(values):
96
values = arrayizeValue(values)
97
98
for value in values:
99
value = safeSQLIdentificatorNaming(value)
100
foundDbs.append(value)
101
102
if not values and isInferenceAvailable() and not conf.direct:
103
infoMsg = "fetching number of database"
104
if dbConsider == "1":
105
infoMsg += "s LIKE"
106
infoMsg += " '%s'" % unsafeSQLIdentificatorNaming(db)
107
logger.info(infoMsg)
108
109
if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:
110
query = rootQuery.blind.count2
111
else:
112
query = rootQuery.blind.count
113
114
query = query % (dbQuery + exclDbsQuery)
115
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
116
117
if not isNumPosStrValue(count):
118
warnMsg = "no database"
119
if dbConsider == "1":
120
warnMsg += "s LIKE"
121
warnMsg += " '%s' found" % unsafeSQLIdentificatorNaming(db)
122
logger.warning(warnMsg)
123
124
continue
125
126
indexRange = getLimitRange(count)
127
128
for index in indexRange:
129
if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:
130
query = rootQuery.blind.query2
131
else:
132
query = rootQuery.blind.query
133
134
query = query % (dbQuery + exclDbsQuery)
135
query = agent.limitQuery(index, query, dbCond)
136
137
value = unArrayizeValue(inject.getValue(query, union=False, error=False))
138
value = safeSQLIdentificatorNaming(value)
139
foundDbs.append(value)
140
141
conf.dumper.lister("found databases", foundDbs)
142
143
def searchTable(self):
144
bruteForce = False
145
146
if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:
147
errMsg = "information_schema not available, "
148
errMsg += "back-end DBMS is MySQL < 5.0"
149
bruteForce = True
150
151
if bruteForce:
152
message = "do you want to use common table existence check? %s" % ("[Y/n/q]" if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI, DBMS.EXTREMEDB) else "[y/N/q]")
153
choice = readInput(message, default='Y' if 'Y' in message else 'N').upper()
154
155
if choice == 'N':
156
return
157
elif choice == 'Q':
158
raise SqlmapUserQuitException
159
else:
160
regex = '|'.join(conf.tbl.split(','))
161
return tableExists(paths.COMMON_TABLES, regex)
162
163
foundTbls = {}
164
tblList = conf.tbl.split(',')
165
rootQuery = queries[Backend.getIdentifiedDbms()].search_table
166
tblCond = rootQuery.inband.condition
167
dbCond = rootQuery.inband.condition2
168
tblConsider, tblCondParam = self.likeOrExact("table")
169
170
for tbl in tblList:
171
values = []
172
tbl = safeSQLIdentificatorNaming(tbl, True)
173
174
if Backend.getIdentifiedDbms() in UPPER_CASE_DBMSES:
175
tbl = tbl.upper()
176
conf.db = conf.db.upper() if conf.db else conf.db
177
178
infoMsg = "searching table"
179
if tblConsider == '1':
180
infoMsg += "s LIKE"
181
infoMsg += " '%s'" % unsafeSQLIdentificatorNaming(tbl)
182
183
if conf.db == CURRENT_DB:
184
conf.db = self.getCurrentDb()
185
186
if dbCond and conf.db:
187
_ = conf.db.split(',')
188
whereDbsQuery = " AND (" + " OR ".join("%s = '%s'" % (dbCond, unsafeSQLIdentificatorNaming(db)) for db in _) + ")"
189
infoMsg += " for database%s '%s'" % ("s" if len(_) > 1 else "", ", ".join(db for db in _))
190
elif conf.excludeSysDbs:
191
whereDbsQuery = "".join(" AND '%s' != %s" % (unsafeSQLIdentificatorNaming(db), dbCond) for db in self.excludeDbsList)
192
msg = "skipping system database%s '%s'" % ("s" if len(self.excludeDbsList) > 1 else "", ", ".join(db for db in self.excludeDbsList))
193
logger.info(msg)
194
else:
195
whereDbsQuery = ""
196
197
if dbCond and conf.exclude:
198
whereDbsQuery += " AND %s NOT LIKE '%s'" % (dbCond, re.sub(r"\.[*+]", '%', conf.exclude._original))
199
200
logger.info(infoMsg)
201
202
tblQuery = "%s%s" % (tblCond, tblCondParam)
203
tblQuery = tblQuery % unsafeSQLIdentificatorNaming(tbl)
204
205
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
206
query = rootQuery.inband.query
207
208
query = query % (tblQuery + whereDbsQuery)
209
values = inject.getValue(query, blind=False, time=False)
210
211
if values and Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.FIREBIRD):
212
newValues = []
213
214
if isinstance(values, six.string_types):
215
values = [values]
216
for value in values:
217
dbName = "SQLite" if Backend.isDbms(DBMS.SQLITE) else "Firebird"
218
newValues.append(["%s%s" % (dbName, METADB_SUFFIX), value])
219
220
values = newValues
221
222
for foundDb, foundTbl in filterPairValues(values):
223
foundDb = safeSQLIdentificatorNaming(foundDb)
224
foundTbl = safeSQLIdentificatorNaming(foundTbl, True)
225
226
if foundDb is None or foundTbl is None:
227
continue
228
229
if foundDb in foundTbls:
230
foundTbls[foundDb].append(foundTbl)
231
else:
232
foundTbls[foundDb] = [foundTbl]
233
234
if not values and isInferenceAvailable() and not conf.direct:
235
if Backend.getIdentifiedDbms() not in (DBMS.SQLITE, DBMS.FIREBIRD):
236
if len(whereDbsQuery) == 0:
237
infoMsg = "fetching number of databases with table"
238
if tblConsider == "1":
239
infoMsg += "s LIKE"
240
infoMsg += " '%s'" % unsafeSQLIdentificatorNaming(tbl)
241
logger.info(infoMsg)
242
243
query = rootQuery.blind.count
244
query = query % (tblQuery + whereDbsQuery)
245
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
246
247
if not isNumPosStrValue(count):
248
warnMsg = "no databases have table"
249
if tblConsider == "1":
250
warnMsg += "s LIKE"
251
warnMsg += " '%s'" % unsafeSQLIdentificatorNaming(tbl)
252
logger.warning(warnMsg)
253
254
continue
255
256
indexRange = getLimitRange(count)
257
258
for index in indexRange:
259
query = rootQuery.blind.query
260
query = query % (tblQuery + whereDbsQuery)
261
query = agent.limitQuery(index, query)
262
263
foundDb = unArrayizeValue(inject.getValue(query, union=False, error=False))
264
foundDb = safeSQLIdentificatorNaming(foundDb)
265
266
if foundDb not in foundTbls:
267
foundTbls[foundDb] = []
268
269
if tblConsider == "2":
270
foundTbls[foundDb].append(tbl)
271
272
if tblConsider == "2":
273
continue
274
else:
275
for db in conf.db.split(',') if conf.db else (self.getCurrentDb(),):
276
db = safeSQLIdentificatorNaming(db)
277
if db not in foundTbls:
278
foundTbls[db] = []
279
else:
280
dbName = "SQLite" if Backend.isDbms(DBMS.SQLITE) else "Firebird"
281
foundTbls["%s%s" % (dbName, METADB_SUFFIX)] = []
282
283
for db in foundTbls:
284
db = safeSQLIdentificatorNaming(db)
285
286
infoMsg = "fetching number of table"
287
if tblConsider == "1":
288
infoMsg += "s LIKE"
289
infoMsg += " '%s' in database '%s'" % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(db))
290
logger.info(infoMsg)
291
292
query = rootQuery.blind.count2
293
if Backend.getIdentifiedDbms() not in (DBMS.SQLITE, DBMS.FIREBIRD):
294
query = query % unsafeSQLIdentificatorNaming(db)
295
query += " AND %s" % tblQuery
296
297
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
298
299
if not isNumPosStrValue(count):
300
warnMsg = "no table"
301
if tblConsider == "1":
302
warnMsg += "s LIKE"
303
warnMsg += " '%s' " % unsafeSQLIdentificatorNaming(tbl)
304
warnMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(db)
305
logger.warning(warnMsg)
306
307
continue
308
309
indexRange = getLimitRange(count)
310
311
for index in indexRange:
312
query = rootQuery.blind.query2
313
314
if " ORDER BY " in query:
315
query = query.replace(" ORDER BY ", "%s ORDER BY " % (" AND %s" % tblQuery))
316
elif query.endswith("'%s')"):
317
query = query[:-1] + " AND %s)" % tblQuery
318
else:
319
query += " AND %s" % tblQuery
320
321
if Backend.isDbms(DBMS.FIREBIRD):
322
query = safeStringFormat(query, index)
323
324
if Backend.getIdentifiedDbms() not in (DBMS.SQLITE, DBMS.FIREBIRD):
325
query = safeStringFormat(query, unsafeSQLIdentificatorNaming(db))
326
327
if not Backend.isDbms(DBMS.FIREBIRD):
328
query = agent.limitQuery(index, query)
329
330
foundTbl = unArrayizeValue(inject.getValue(query, union=False, error=False))
331
if not isNoneValue(foundTbl):
332
kb.hintValue = foundTbl
333
foundTbl = safeSQLIdentificatorNaming(foundTbl, True)
334
foundTbls[db].append(foundTbl)
335
336
for db in list(foundTbls.keys()):
337
if isNoneValue(foundTbls[db]):
338
del foundTbls[db]
339
340
if not foundTbls:
341
warnMsg = "no databases contain any of the provided tables"
342
logger.warning(warnMsg)
343
return
344
345
conf.dumper.dbTables(foundTbls)
346
self.dumpFoundTables(foundTbls)
347
348
def searchColumn(self):
349
bruteForce = False
350
351
self.forceDbmsEnum()
352
353
if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:
354
errMsg = "information_schema not available, "
355
errMsg += "back-end DBMS is MySQL < 5.0"
356
bruteForce = True
357
358
if bruteForce:
359
message = "do you want to use common column existence check? %s" % ("[Y/n/q]" if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI, DBMS.EXTREMEDB) else "[y/N/q]")
360
choice = readInput(message, default='Y' if 'Y' in message else 'N').upper()
361
362
if choice == 'N':
363
return
364
elif choice == 'Q':
365
raise SqlmapUserQuitException
366
else:
367
regex = '|'.join(conf.col.split(','))
368
conf.dumper.dbTableColumns(columnExists(paths.COMMON_COLUMNS, regex))
369
370
message = "do you want to dump entries? [Y/n] "
371
372
if readInput(message, default='Y', boolean=True):
373
self.dumpAll()
374
375
return
376
377
rootQuery = queries[Backend.getIdentifiedDbms()].search_column
378
foundCols = {}
379
dbs = {}
380
whereDbsQuery = ""
381
whereTblsQuery = ""
382
infoMsgTbl = ""
383
infoMsgDb = ""
384
colList = conf.col.split(',')
385
386
if conf.exclude:
387
colList = [_ for _ in colList if re.search(conf.exclude, _, re.I) is None]
388
389
origTbl = conf.tbl
390
origDb = conf.db
391
colCond = rootQuery.inband.condition
392
dbCond = rootQuery.inband.condition2
393
tblCond = rootQuery.inband.condition3
394
colConsider, colCondParam = self.likeOrExact("column")
395
396
for column in colList:
397
values = []
398
column = safeSQLIdentificatorNaming(column)
399
conf.db = origDb
400
conf.tbl = origTbl
401
402
if Backend.getIdentifiedDbms() in UPPER_CASE_DBMSES:
403
column = column.upper()
404
conf.db = conf.db.upper() if conf.db else conf.db
405
conf.tbl = conf.tbl.upper() if conf.tbl else conf.tbl
406
407
infoMsg = "searching column"
408
if colConsider == "1":
409
infoMsg += "s LIKE"
410
infoMsg += " '%s'" % unsafeSQLIdentificatorNaming(column)
411
412
foundCols[column] = {}
413
414
if tblCond:
415
if conf.tbl:
416
tbls = conf.tbl.split(',')
417
if conf.exclude:
418
tbls = [_ for _ in tbls if re.search(conf.exclude, _, re.I) is None]
419
whereTblsQuery = " AND (" + " OR ".join("%s = '%s'" % (tblCond, unsafeSQLIdentificatorNaming(tbl)) for tbl in tbls) + ")"
420
infoMsgTbl = " for table%s '%s'" % ("s" if len(tbls) > 1 else "", ", ".join(unsafeSQLIdentificatorNaming(tbl) for tbl in tbls))
421
422
if conf.db == CURRENT_DB:
423
conf.db = self.getCurrentDb()
424
425
if dbCond:
426
if conf.db:
427
_ = conf.db.split(',')
428
whereDbsQuery = " AND (" + " OR ".join("%s = '%s'" % (dbCond, unsafeSQLIdentificatorNaming(db)) for db in _) + ")"
429
infoMsgDb = " in database%s '%s'" % ("s" if len(_) > 1 else "", ", ".join(unsafeSQLIdentificatorNaming(db) for db in _))
430
elif conf.excludeSysDbs:
431
whereDbsQuery = "".join(" AND %s != '%s'" % (dbCond, unsafeSQLIdentificatorNaming(db)) for db in self.excludeDbsList)
432
msg = "skipping system database%s '%s'" % ("s" if len(self.excludeDbsList) > 1 else "", ", ".join(unsafeSQLIdentificatorNaming(db) for db in self.excludeDbsList))
433
logger.info(msg)
434
else:
435
infoMsgDb = " across all databases"
436
437
if conf.exclude:
438
whereDbsQuery += " AND %s NOT LIKE '%s'" % (dbCond, re.sub(r"\.[*+]", '%', conf.exclude._original))
439
440
logger.info("%s%s%s" % (infoMsg, infoMsgTbl, infoMsgDb))
441
442
colQuery = "%s%s" % (colCond, colCondParam)
443
colQuery = colQuery % unsafeSQLIdentificatorNaming(column)
444
445
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
446
if not all((conf.db, conf.tbl)):
447
# Enumerate tables containing the column provided if
448
# either of database(s) or table(s) is not provided
449
query = rootQuery.inband.query
450
query = query % (colQuery + whereDbsQuery + whereTblsQuery)
451
values = inject.getValue(query, blind=False, time=False)
452
else:
453
# Assume provided databases' tables contain the
454
# column(s) provided
455
values = []
456
457
for db in conf.db.split(','):
458
for tbl in conf.tbl.split(','):
459
values.append([safeSQLIdentificatorNaming(db), safeSQLIdentificatorNaming(tbl, True)])
460
461
for db, tbl in filterPairValues(values):
462
db = safeSQLIdentificatorNaming(db)
463
tbls = tbl.split(',') if not isNoneValue(tbl) else []
464
465
for tbl in tbls:
466
tbl = safeSQLIdentificatorNaming(tbl, True)
467
468
if db is None or tbl is None:
469
continue
470
471
conf.db = db
472
conf.tbl = tbl
473
conf.col = column
474
475
self.getColumns(onlyColNames=True, colTuple=(colConsider, colCondParam), bruteForce=False)
476
477
if db in kb.data.cachedColumns and tbl in kb.data.cachedColumns[db]:
478
if db not in dbs:
479
dbs[db] = {}
480
481
if tbl not in dbs[db]:
482
dbs[db][tbl] = {}
483
484
dbs[db][tbl].update(kb.data.cachedColumns[db][tbl])
485
486
if db in foundCols[column]:
487
foundCols[column][db].append(tbl)
488
else:
489
foundCols[column][db] = [tbl]
490
491
kb.data.cachedColumns = {}
492
493
if not values and isInferenceAvailable() and not conf.direct:
494
if not conf.db:
495
infoMsg = "fetching number of databases with tables containing column"
496
if colConsider == "1":
497
infoMsg += "s LIKE"
498
infoMsg += " '%s'" % unsafeSQLIdentificatorNaming(column)
499
logger.info("%s%s%s" % (infoMsg, infoMsgTbl, infoMsgDb))
500
501
query = rootQuery.blind.count
502
query = query % (colQuery + whereDbsQuery + whereTblsQuery)
503
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
504
505
if not isNumPosStrValue(count):
506
warnMsg = "no databases have tables containing column"
507
if colConsider == "1":
508
warnMsg += "s LIKE"
509
warnMsg += " '%s'" % unsafeSQLIdentificatorNaming(column)
510
logger.warning("%s%s" % (warnMsg, infoMsgTbl))
511
512
continue
513
514
indexRange = getLimitRange(count)
515
516
for index in indexRange:
517
query = rootQuery.blind.query
518
query = query % (colQuery + whereDbsQuery + whereTblsQuery)
519
query = agent.limitQuery(index, query)
520
521
db = unArrayizeValue(inject.getValue(query, union=False, error=False))
522
db = safeSQLIdentificatorNaming(db)
523
524
if db not in dbs:
525
dbs[db] = {}
526
527
if db not in foundCols[column]:
528
foundCols[column][db] = []
529
else:
530
for db in conf.db.split(',') if conf.db else (self.getCurrentDb(),):
531
db = safeSQLIdentificatorNaming(db)
532
if db not in foundCols[column]:
533
foundCols[column][db] = []
534
535
origDb = conf.db
536
origTbl = conf.tbl
537
538
for column, dbData in foundCols.items():
539
colQuery = "%s%s" % (colCond, colCondParam)
540
colQuery = colQuery % unsafeSQLIdentificatorNaming(column)
541
542
for db in dbData:
543
conf.db = origDb
544
conf.tbl = origTbl
545
546
infoMsg = "fetching number of tables containing column"
547
if colConsider == "1":
548
infoMsg += "s LIKE"
549
infoMsg += " '%s' in database '%s'" % (unsafeSQLIdentificatorNaming(column), unsafeSQLIdentificatorNaming(db))
550
logger.info(infoMsg)
551
552
query = rootQuery.blind.count2
553
if not re.search(r"(?i)%s\Z" % METADB_SUFFIX, db or ""):
554
query = query % unsafeSQLIdentificatorNaming(db)
555
query += " AND %s" % colQuery
556
else:
557
query = query % colQuery
558
559
query += whereTblsQuery
560
561
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
562
563
if not isNumPosStrValue(count):
564
warnMsg = "no tables contain column"
565
if colConsider == "1":
566
warnMsg += "s LIKE"
567
warnMsg += " '%s' " % unsafeSQLIdentificatorNaming(column)
568
warnMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(db)
569
logger.warning(warnMsg)
570
571
continue
572
573
indexRange = getLimitRange(count)
574
575
for index in indexRange:
576
query = rootQuery.blind.query2
577
578
if re.search(r"(?i)%s\Z" % METADB_SUFFIX, db or ""):
579
query = query % (colQuery + whereTblsQuery)
580
elif query.endswith("'%s')"):
581
query = query[:-1] + " AND %s)" % (colQuery + whereTblsQuery)
582
elif " ORDER BY " in query:
583
query = query.replace(" ORDER BY ", " AND %s ORDER BY " % (colQuery + whereTblsQuery))
584
else:
585
query += " AND %s" % (colQuery + whereTblsQuery)
586
587
query = safeStringFormat(query, unsafeSQLIdentificatorNaming(db))
588
query = agent.limitQuery(index, query)
589
590
tbl = unArrayizeValue(inject.getValue(query, union=False, error=False))
591
kb.hintValue = tbl
592
593
tbl = safeSQLIdentificatorNaming(tbl, True)
594
595
conf.db = db
596
conf.tbl = tbl
597
conf.col = column
598
599
self.getColumns(onlyColNames=True, colTuple=(colConsider, colCondParam), bruteForce=False)
600
601
if db in kb.data.cachedColumns and tbl in kb.data.cachedColumns[db]:
602
if db not in dbs:
603
dbs[db] = {}
604
605
if tbl not in dbs[db]:
606
dbs[db][tbl] = {}
607
608
dbs[db][tbl].update(kb.data.cachedColumns[db][tbl])
609
610
kb.data.cachedColumns = {}
611
612
if db in foundCols[column]:
613
foundCols[column][db].append(tbl)
614
else:
615
foundCols[column][db] = [tbl]
616
617
if dbs:
618
conf.dumper.dbColumns(foundCols, colConsider, dbs)
619
self.dumpFoundColumn(dbs, foundCols, colConsider)
620
else:
621
warnMsg = "no databases have tables containing any of the "
622
warnMsg += "provided columns"
623
logger.warning(warnMsg)
624
625
def search(self):
626
if Backend.getIdentifiedDbms() in UPPER_CASE_DBMSES:
627
for item in ('db', 'tbl', 'col'):
628
if getattr(conf, item, None):
629
setattr(conf, item, getattr(conf, item).upper())
630
631
if conf.col:
632
self.searchColumn()
633
elif conf.tbl:
634
self.searchTable()
635
elif conf.db:
636
self.searchDb()
637
else:
638
errMsg = "missing parameter, provide -D, -T or -C along "
639
errMsg += "with --search"
640
raise SqlmapMissingMandatoryOptionException(errMsg)
641
642