Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sqlmapproject
GitHub Repository: sqlmapproject/sqlmap
Path: blob/master/lib/core/dump.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 hashlib
9
import os
10
import re
11
import shutil
12
import tempfile
13
import threading
14
15
from lib.core.common import Backend
16
from lib.core.common import checkFile
17
from lib.core.common import dataToDumpFile
18
from lib.core.common import dataToStdout
19
from lib.core.common import filterNone
20
from lib.core.common import getSafeExString
21
from lib.core.common import isListLike
22
from lib.core.common import isNoneValue
23
from lib.core.common import normalizeUnicode
24
from lib.core.common import openFile
25
from lib.core.common import prioritySortColumns
26
from lib.core.common import randomInt
27
from lib.core.common import safeCSValue
28
from lib.core.common import unArrayizeValue
29
from lib.core.common import unsafeSQLIdentificatorNaming
30
from lib.core.compat import xrange
31
from lib.core.convert import getBytes
32
from lib.core.convert import getConsoleLength
33
from lib.core.convert import getText
34
from lib.core.convert import getUnicode
35
from lib.core.convert import htmlEscape
36
from lib.core.data import conf
37
from lib.core.data import kb
38
from lib.core.data import logger
39
from lib.core.dicts import DUMP_REPLACEMENTS
40
from lib.core.enums import CONTENT_STATUS
41
from lib.core.enums import CONTENT_TYPE
42
from lib.core.enums import DBMS
43
from lib.core.enums import DUMP_FORMAT
44
from lib.core.exception import SqlmapGenericException
45
from lib.core.exception import SqlmapSystemException
46
from lib.core.exception import SqlmapValueException
47
from lib.core.replication import Replication
48
from lib.core.settings import DUMP_FILE_BUFFER_SIZE
49
from lib.core.settings import HTML_DUMP_CSS_STYLE
50
from lib.core.settings import IS_WIN
51
from lib.core.settings import METADB_SUFFIX
52
from lib.core.settings import MIN_BINARY_DISK_DUMP_SIZE
53
from lib.core.settings import TRIM_STDOUT_DUMP_SIZE
54
from lib.core.settings import UNICODE_ENCODING
55
from lib.core.settings import UNSAFE_DUMP_FILEPATH_REPLACEMENT
56
from lib.core.settings import VERSION_STRING
57
from lib.core.settings import WINDOWS_RESERVED_NAMES
58
from lib.utils.safe2bin import safechardecode
59
from thirdparty import six
60
from thirdparty.magic import magic
61
62
class Dump(object):
63
"""
64
This class defines methods used to parse and output the results
65
of SQL injection actions
66
"""
67
68
def __init__(self):
69
self._outputFile = None
70
self._outputFP = None
71
self._lock = threading.Lock()
72
73
def _write(self, data, newline=True, console=True, content_type=None):
74
text = "%s%s" % (data, "\n" if newline else " ")
75
76
if conf.api:
77
dataToStdout(data, contentType=content_type, status=CONTENT_STATUS.COMPLETE)
78
79
elif console:
80
dataToStdout(text)
81
82
if self._outputFP:
83
multiThreadMode = kb.multiThreadMode
84
if multiThreadMode:
85
self._lock.acquire()
86
87
try:
88
self._outputFP.write(text)
89
except IOError as ex:
90
errMsg = "error occurred while writing to log file ('%s')" % getSafeExString(ex)
91
raise SqlmapGenericException(errMsg)
92
93
if multiThreadMode:
94
self._lock.release()
95
96
kb.dataOutputFlag = True
97
98
def flush(self):
99
if self._outputFP:
100
try:
101
self._outputFP.flush()
102
except IOError:
103
pass
104
105
def setOutputFile(self):
106
if conf.noLogging:
107
self._outputFP = None
108
return
109
110
self._outputFile = os.path.join(conf.outputPath, "log")
111
try:
112
self._outputFP = openFile(self._outputFile, "ab" if not conf.flushSession else "wb")
113
except IOError as ex:
114
errMsg = "error occurred while opening log file ('%s')" % getSafeExString(ex)
115
raise SqlmapGenericException(errMsg)
116
117
def singleString(self, data, content_type=None):
118
self._write(data, content_type=content_type)
119
120
def string(self, header, data, content_type=None, sort=True):
121
if conf.api:
122
self._write(data, content_type=content_type)
123
124
if isListLike(data) and len(data) == 1:
125
data = unArrayizeValue(data)
126
127
if isListLike(data):
128
self.lister(header, data, content_type, sort)
129
elif data is not None:
130
_ = getUnicode(data)
131
132
if _.endswith("\r\n"):
133
_ = _[:-2]
134
135
elif _.endswith("\n"):
136
_ = _[:-1]
137
138
if _.strip(' '):
139
_ = _.strip(' ')
140
141
if "\n" in _:
142
self._write("%s:\n---\n%s\n---" % (header, _))
143
else:
144
self._write("%s: %s" % (header, ("'%s'" % _) if isinstance(data, six.string_types) else _))
145
146
def lister(self, header, elements, content_type=None, sort=True):
147
if elements and sort:
148
try:
149
elements = set(elements)
150
elements = list(elements)
151
elements.sort(key=lambda _: _.lower() if hasattr(_, "lower") else _)
152
except:
153
pass
154
155
if conf.api:
156
self._write(elements, content_type=content_type)
157
158
if elements:
159
self._write("%s [%d]:" % (header, len(elements)))
160
161
for element in elements:
162
if isinstance(element, six.string_types):
163
self._write("[*] %s" % element)
164
elif isListLike(element):
165
self._write("[*] " + ", ".join(getUnicode(e) for e in element))
166
167
if elements:
168
self._write("")
169
170
def banner(self, data):
171
self.string("banner", data, content_type=CONTENT_TYPE.BANNER)
172
173
def currentUser(self, data):
174
self.string("current user", data, content_type=CONTENT_TYPE.CURRENT_USER)
175
176
def currentDb(self, data):
177
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB, DBMS.CACHE, DBMS.FRONTBASE):
178
self.string("current database (equivalent to schema on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
179
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.DB2, DBMS.MIMERSQL, DBMS.MAXDB, DBMS.VIRTUOSO):
180
self.string("current database (equivalent to owner on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
181
else:
182
self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB)
183
184
def hostname(self, data):
185
self.string("hostname", data, content_type=CONTENT_TYPE.HOSTNAME)
186
187
def dba(self, data):
188
self.string("current user is DBA", data, content_type=CONTENT_TYPE.IS_DBA)
189
190
def users(self, users):
191
self.lister("database management system users", users, content_type=CONTENT_TYPE.USERS)
192
193
def statements(self, statements):
194
self.lister("SQL statements", statements, content_type=CONTENT_TYPE.STATEMENTS)
195
196
def userSettings(self, header, userSettings, subHeader, content_type=None):
197
self._areAdmins = set()
198
199
if isinstance(userSettings, (tuple, list, set)):
200
self._areAdmins = userSettings[1]
201
userSettings = userSettings[0]
202
203
users = [_ for _ in userSettings.keys() if _ is not None]
204
users.sort(key=lambda _: _.lower() if hasattr(_, "lower") else _)
205
206
if conf.api:
207
self._write(userSettings, content_type=content_type)
208
209
if userSettings:
210
self._write("%s:" % header)
211
212
for user in users:
213
settings = filterNone(userSettings[user])
214
215
if isNoneValue(settings):
216
stringSettings = ""
217
else:
218
stringSettings = " [%d]:" % len(settings)
219
220
if user in self._areAdmins:
221
self._write("[*] %s (administrator)%s" % (user, stringSettings))
222
else:
223
self._write("[*] %s%s" % (user, stringSettings))
224
225
if settings:
226
settings.sort()
227
228
for setting in settings:
229
self._write(" %s: %s" % (subHeader, setting))
230
231
if userSettings:
232
self.singleString("")
233
234
def dbs(self, dbs):
235
self.lister("available databases", dbs, content_type=CONTENT_TYPE.DBS)
236
237
def dbTables(self, dbTables):
238
if isinstance(dbTables, dict) and len(dbTables) > 0:
239
if conf.api:
240
self._write(dbTables, content_type=CONTENT_TYPE.TABLES)
241
242
maxlength = 0
243
244
for tables in dbTables.values():
245
for table in tables:
246
if table and isListLike(table):
247
table = table[0]
248
249
maxlength = max(maxlength, getConsoleLength(unsafeSQLIdentificatorNaming(getUnicode(table))))
250
251
lines = "-" * (int(maxlength) + 2)
252
253
for db, tables in dbTables.items():
254
tables = sorted(filter(None, tables))
255
256
self._write("Database: %s" % unsafeSQLIdentificatorNaming(db) if db and METADB_SUFFIX not in db else "<current>")
257
258
if len(tables) == 1:
259
self._write("[1 table]")
260
else:
261
self._write("[%d tables]" % len(tables))
262
263
self._write("+%s+" % lines)
264
265
for table in tables:
266
if table and isListLike(table):
267
table = table[0]
268
269
table = unsafeSQLIdentificatorNaming(table)
270
blank = " " * (maxlength - getConsoleLength(getUnicode(table)))
271
self._write("| %s%s |" % (table, blank))
272
273
self._write("+%s+\n" % lines)
274
elif dbTables is None or len(dbTables) == 0:
275
self.singleString("No tables found", content_type=CONTENT_TYPE.TABLES)
276
else:
277
self.string("tables", dbTables, content_type=CONTENT_TYPE.TABLES)
278
279
def dbTableColumns(self, tableColumns, content_type=None):
280
if isinstance(tableColumns, dict) and len(tableColumns) > 0:
281
if conf.api:
282
self._write(tableColumns, content_type=content_type)
283
284
for db, tables in tableColumns.items():
285
if not db:
286
db = "All"
287
288
for table, columns in tables.items():
289
maxlength1 = 0
290
maxlength2 = 0
291
292
colType = None
293
294
colList = list(columns.keys())
295
colList.sort(key=lambda _: _.lower() if hasattr(_, "lower") else _)
296
297
for column in colList:
298
colType = columns[column]
299
300
column = unsafeSQLIdentificatorNaming(column)
301
maxlength1 = max(maxlength1, len(column or ""))
302
maxlength2 = max(maxlength2, len(colType or ""))
303
304
maxlength1 = max(maxlength1, len("COLUMN"))
305
lines1 = "-" * (maxlength1 + 2)
306
307
if colType is not None:
308
maxlength2 = max(maxlength2, len("TYPE"))
309
lines2 = "-" * (maxlength2 + 2)
310
311
self._write("Database: %s\nTable: %s" % (unsafeSQLIdentificatorNaming(db) if db and METADB_SUFFIX not in db else "<current>", unsafeSQLIdentificatorNaming(table)))
312
313
if len(columns) == 1:
314
self._write("[1 column]")
315
else:
316
self._write("[%d columns]" % len(columns))
317
318
if colType is not None:
319
self._write("+%s+%s+" % (lines1, lines2))
320
else:
321
self._write("+%s+" % lines1)
322
323
blank1 = " " * (maxlength1 - len("COLUMN"))
324
325
if colType is not None:
326
blank2 = " " * (maxlength2 - len("TYPE"))
327
328
if colType is not None:
329
self._write("| Column%s | Type%s |" % (blank1, blank2))
330
self._write("+%s+%s+" % (lines1, lines2))
331
else:
332
self._write("| Column%s |" % blank1)
333
self._write("+%s+" % lines1)
334
335
for column in colList:
336
colType = columns[column]
337
338
column = unsafeSQLIdentificatorNaming(column)
339
blank1 = " " * (maxlength1 - len(column))
340
341
if colType is not None:
342
blank2 = " " * (maxlength2 - len(colType))
343
self._write("| %s%s | %s%s |" % (column, blank1, colType, blank2))
344
else:
345
self._write("| %s%s |" % (column, blank1))
346
347
if colType is not None:
348
self._write("+%s+%s+\n" % (lines1, lines2))
349
else:
350
self._write("+%s+\n" % lines1)
351
352
def dbTablesCount(self, dbTables):
353
if isinstance(dbTables, dict) and len(dbTables) > 0:
354
if conf.api:
355
self._write(dbTables, content_type=CONTENT_TYPE.COUNT)
356
357
maxlength1 = len("Table")
358
maxlength2 = len("Entries")
359
360
for ctables in dbTables.values():
361
for tables in ctables.values():
362
for table in tables:
363
maxlength1 = max(maxlength1, getConsoleLength(getUnicode(table)))
364
365
for db, counts in dbTables.items():
366
self._write("Database: %s" % unsafeSQLIdentificatorNaming(db) if db and METADB_SUFFIX not in db else "<current>")
367
368
lines1 = "-" * (maxlength1 + 2)
369
blank1 = " " * (maxlength1 - len("Table"))
370
lines2 = "-" * (maxlength2 + 2)
371
blank2 = " " * (maxlength2 - len("Entries"))
372
373
self._write("+%s+%s+" % (lines1, lines2))
374
self._write("| Table%s | Entries%s |" % (blank1, blank2))
375
self._write("+%s+%s+" % (lines1, lines2))
376
377
sortedCounts = list(counts.keys())
378
sortedCounts.sort(reverse=True)
379
380
for count in sortedCounts:
381
tables = counts[count]
382
383
if count is None:
384
count = "Unknown"
385
386
tables.sort(key=lambda _: _.lower() if hasattr(_, "lower") else _)
387
388
for table in tables:
389
blank1 = " " * (maxlength1 - getConsoleLength(getUnicode(table)))
390
blank2 = " " * (maxlength2 - len(str(count)))
391
self._write("| %s%s | %d%s |" % (table, blank1, count, blank2))
392
393
self._write("+%s+%s+\n" % (lines1, lines2))
394
else:
395
logger.error("unable to retrieve the number of entries for any table")
396
397
def dbTableValues(self, tableValues):
398
replication = None
399
rtable = None
400
dumpFP = None
401
appendToFile = False
402
warnFile = False
403
404
if tableValues is None:
405
return
406
407
db = tableValues["__infos__"]["db"]
408
if not db:
409
db = "All"
410
table = tableValues["__infos__"]["table"]
411
412
if conf.api:
413
self._write(tableValues, content_type=CONTENT_TYPE.DUMP_TABLE)
414
415
try:
416
dumpDbPath = os.path.join(conf.dumpPath, unsafeSQLIdentificatorNaming(db))
417
except UnicodeError:
418
try:
419
dumpDbPath = os.path.join(conf.dumpPath, normalizeUnicode(unsafeSQLIdentificatorNaming(db)))
420
except (UnicodeError, OSError):
421
tempDir = tempfile.mkdtemp(prefix="sqlmapdb")
422
warnMsg = "currently unable to use regular dump directory. "
423
warnMsg += "Using temporary directory '%s' instead" % tempDir
424
logger.warning(warnMsg)
425
426
dumpDbPath = tempDir
427
428
if conf.dumpFormat == DUMP_FORMAT.SQLITE:
429
replication = Replication(os.path.join(conf.dumpPath, "%s.sqlite3" % unsafeSQLIdentificatorNaming(db)))
430
elif conf.dumpFormat in (DUMP_FORMAT.CSV, DUMP_FORMAT.HTML):
431
if not os.path.isdir(dumpDbPath):
432
try:
433
os.makedirs(dumpDbPath)
434
except:
435
warnFile = True
436
437
_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, unsafeSQLIdentificatorNaming(db))
438
dumpDbPath = os.path.join(conf.dumpPath, "%s-%s" % (_, hashlib.md5(getBytes(db)).hexdigest()[:8]))
439
440
if not os.path.isdir(dumpDbPath):
441
try:
442
os.makedirs(dumpDbPath)
443
except Exception as ex:
444
tempDir = tempfile.mkdtemp(prefix="sqlmapdb")
445
warnMsg = "unable to create dump directory "
446
warnMsg += "'%s' (%s). " % (dumpDbPath, getSafeExString(ex))
447
warnMsg += "Using temporary directory '%s' instead" % tempDir
448
logger.warning(warnMsg)
449
450
dumpDbPath = tempDir
451
452
dumpFileName = conf.dumpFile or os.path.join(dumpDbPath, re.sub(r'[\\/]', UNSAFE_DUMP_FILEPATH_REPLACEMENT, "%s.%s" % (unsafeSQLIdentificatorNaming(table), conf.dumpFormat.lower())))
453
if not checkFile(dumpFileName, False):
454
try:
455
openFile(dumpFileName, "w+b").close()
456
except SqlmapSystemException:
457
raise
458
except:
459
warnFile = True
460
461
_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, normalizeUnicode(unsafeSQLIdentificatorNaming(table)))
462
if len(_) < len(table) or IS_WIN and table.upper() in WINDOWS_RESERVED_NAMES:
463
_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, unsafeSQLIdentificatorNaming(table))
464
dumpFileName = os.path.join(dumpDbPath, "%s-%s.%s" % (_, hashlib.md5(getBytes(table)).hexdigest()[:8], conf.dumpFormat.lower()))
465
else:
466
dumpFileName = os.path.join(dumpDbPath, "%s.%s" % (_, conf.dumpFormat.lower()))
467
else:
468
appendToFile = any((conf.limitStart, conf.limitStop))
469
470
if not appendToFile:
471
count = 1
472
while True:
473
candidate = "%s.%d" % (dumpFileName, count)
474
if not checkFile(candidate, False):
475
try:
476
shutil.copyfile(dumpFileName, candidate)
477
except IOError:
478
pass
479
break
480
else:
481
count += 1
482
483
dumpFP = openFile(dumpFileName, "wb" if not appendToFile else "ab", buffering=DUMP_FILE_BUFFER_SIZE)
484
485
count = int(tableValues["__infos__"]["count"])
486
separator = str()
487
field = 1
488
fields = len(tableValues) - 1
489
490
columns = prioritySortColumns(list(tableValues.keys()))
491
492
if conf.col:
493
cols = conf.col.split(',')
494
columns = sorted(columns, key=lambda _: cols.index(_) if _ in cols else 0)
495
496
for column in columns:
497
if column != "__infos__":
498
info = tableValues[column]
499
lines = "-" * (int(info["length"]) + 2)
500
separator += "+%s" % lines
501
502
separator += "+"
503
self._write("Database: %s\nTable: %s" % (unsafeSQLIdentificatorNaming(db) if db and METADB_SUFFIX not in db else "<current>", unsafeSQLIdentificatorNaming(table)))
504
505
if conf.dumpFormat == DUMP_FORMAT.SQLITE:
506
cols = []
507
508
for column in columns:
509
if column != "__infos__":
510
colType = Replication.INTEGER
511
512
for value in tableValues[column]['values']:
513
try:
514
if not value or value == " ": # NULL
515
continue
516
517
int(value)
518
except ValueError:
519
colType = None
520
break
521
522
if colType is None:
523
colType = Replication.REAL
524
525
for value in tableValues[column]['values']:
526
try:
527
if not value or value == " ": # NULL
528
continue
529
530
float(value)
531
except ValueError:
532
colType = None
533
break
534
535
cols.append((unsafeSQLIdentificatorNaming(column), colType if colType else Replication.TEXT))
536
537
rtable = replication.createTable(table, cols)
538
elif conf.dumpFormat == DUMP_FORMAT.HTML:
539
dataToDumpFile(dumpFP, "<!DOCTYPE html>\n<html>\n<head>\n")
540
dataToDumpFile(dumpFP, "<meta http-equiv=\"Content-type\" content=\"text/html;charset=%s\">\n" % UNICODE_ENCODING)
541
dataToDumpFile(dumpFP, "<meta name=\"generator\" content=\"%s\" />\n" % VERSION_STRING)
542
dataToDumpFile(dumpFP, "<title>%s</title>\n" % ("%s%s" % ("%s." % db if METADB_SUFFIX not in db else "", table)))
543
dataToDumpFile(dumpFP, HTML_DUMP_CSS_STYLE)
544
dataToDumpFile(dumpFP, "\n</head>\n<body>\n<table>\n<thead>\n<tr>\n")
545
546
if count == 1:
547
self._write("[1 entry]")
548
else:
549
self._write("[%d entries]" % count)
550
551
self._write(separator)
552
553
for column in columns:
554
if column != "__infos__":
555
info = tableValues[column]
556
557
column = unsafeSQLIdentificatorNaming(column)
558
maxlength = int(info["length"])
559
blank = " " * (maxlength - getConsoleLength(column))
560
561
self._write("| %s%s" % (column, blank), newline=False)
562
563
if not appendToFile:
564
if conf.dumpFormat == DUMP_FORMAT.CSV:
565
if field == fields:
566
dataToDumpFile(dumpFP, "%s" % safeCSValue(column))
567
else:
568
dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(column), conf.csvDel))
569
elif conf.dumpFormat == DUMP_FORMAT.HTML:
570
dataToDumpFile(dumpFP, "<th>%s</th>" % getUnicode(htmlEscape(column).encode("ascii", "xmlcharrefreplace")))
571
572
field += 1
573
574
if conf.dumpFormat == DUMP_FORMAT.HTML:
575
dataToDumpFile(dumpFP, "\n</tr>\n</thead>\n<tbody>\n")
576
577
self._write("|\n%s" % separator)
578
579
if conf.dumpFormat == DUMP_FORMAT.CSV:
580
dataToDumpFile(dumpFP, "\n" if not appendToFile else "")
581
582
elif conf.dumpFormat == DUMP_FORMAT.SQLITE:
583
rtable.beginTransaction()
584
585
if count > TRIM_STDOUT_DUMP_SIZE:
586
warnMsg = "console output will be trimmed to "
587
warnMsg += "last %d rows due to " % TRIM_STDOUT_DUMP_SIZE
588
warnMsg += "large table size"
589
logger.warning(warnMsg)
590
591
for i in xrange(count):
592
console = (i >= count - TRIM_STDOUT_DUMP_SIZE)
593
field = 1
594
values = []
595
596
if conf.dumpFormat == DUMP_FORMAT.HTML:
597
dataToDumpFile(dumpFP, "<tr>")
598
599
for column in columns:
600
if column != "__infos__":
601
info = tableValues[column]
602
603
if len(info["values"]) <= i:
604
continue
605
606
if info["values"][i] is None:
607
value = u''
608
else:
609
value = getUnicode(info["values"][i])
610
value = DUMP_REPLACEMENTS.get(value, value)
611
612
values.append(value)
613
maxlength = int(info["length"])
614
blank = " " * (maxlength - getConsoleLength(value))
615
self._write("| %s%s" % (value, blank), newline=False, console=console)
616
617
if len(value) > MIN_BINARY_DISK_DUMP_SIZE and r'\x' in value:
618
try:
619
mimetype = getText(magic.from_buffer(value, mime=True))
620
if any(mimetype.startswith(_) for _ in ("application", "image")):
621
if not os.path.isdir(dumpDbPath):
622
os.makedirs(dumpDbPath)
623
624
_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, normalizeUnicode(unsafeSQLIdentificatorNaming(column)))
625
filepath = os.path.join(dumpDbPath, "%s-%d.bin" % (_, randomInt(8)))
626
warnMsg = "writing binary ('%s') content to file '%s' " % (mimetype, filepath)
627
logger.warning(warnMsg)
628
629
with openFile(filepath, "w+b", None) as f:
630
_ = safechardecode(value, True)
631
f.write(_)
632
633
except Exception as ex:
634
logger.debug(getSafeExString(ex))
635
636
if conf.dumpFormat == DUMP_FORMAT.CSV:
637
if field == fields:
638
dataToDumpFile(dumpFP, "%s" % safeCSValue(value))
639
else:
640
dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(value), conf.csvDel))
641
elif conf.dumpFormat == DUMP_FORMAT.HTML:
642
dataToDumpFile(dumpFP, "<td>%s</td>" % getUnicode(htmlEscape(value).encode("ascii", "xmlcharrefreplace")))
643
644
field += 1
645
646
if conf.dumpFormat == DUMP_FORMAT.SQLITE:
647
try:
648
rtable.insert(values)
649
except SqlmapValueException:
650
pass
651
elif conf.dumpFormat == DUMP_FORMAT.CSV:
652
dataToDumpFile(dumpFP, "\n")
653
elif conf.dumpFormat == DUMP_FORMAT.HTML:
654
dataToDumpFile(dumpFP, "</tr>\n")
655
656
self._write("|", console=console)
657
658
self._write("%s\n" % separator)
659
660
if conf.dumpFormat == DUMP_FORMAT.SQLITE:
661
rtable.endTransaction()
662
logger.info("table '%s.%s' dumped to SQLITE database '%s'" % (db, table, replication.dbpath))
663
664
elif conf.dumpFormat in (DUMP_FORMAT.CSV, DUMP_FORMAT.HTML):
665
if conf.dumpFormat == DUMP_FORMAT.HTML:
666
dataToDumpFile(dumpFP, "</tbody>\n</table>\n</body>\n</html>")
667
else:
668
dataToDumpFile(dumpFP, "\n")
669
dumpFP.close()
670
671
msg = "table '%s.%s' dumped to %s file '%s'" % (db, table, conf.dumpFormat, dumpFileName)
672
if not warnFile:
673
logger.info(msg)
674
else:
675
logger.warning(msg)
676
677
def dbColumns(self, dbColumnsDict, colConsider, dbs):
678
if conf.api:
679
self._write(dbColumnsDict, content_type=CONTENT_TYPE.COLUMNS)
680
681
for column in dbColumnsDict.keys():
682
if colConsider == "1":
683
colConsiderStr = "s LIKE '%s' were" % unsafeSQLIdentificatorNaming(column)
684
else:
685
colConsiderStr = " '%s' was" % unsafeSQLIdentificatorNaming(column)
686
687
found = {}
688
for db, tblData in dbs.items():
689
for tbl, colData in tblData.items():
690
for col, dataType in colData.items():
691
if column.lower() in col.lower():
692
if db in found:
693
if tbl in found[db]:
694
found[db][tbl][col] = dataType
695
else:
696
found[db][tbl] = {col: dataType}
697
else:
698
found[db] = {}
699
found[db][tbl] = {col: dataType}
700
701
continue
702
703
if found:
704
msg = "column%s found in the " % colConsiderStr
705
msg += "following databases:"
706
self._write(msg)
707
708
self.dbTableColumns(found)
709
710
def sqlQuery(self, query, queryRes):
711
self.string(query, queryRes, content_type=CONTENT_TYPE.SQL_QUERY)
712
713
def rFile(self, fileData):
714
self.lister("files saved to", fileData, sort=False, content_type=CONTENT_TYPE.FILE_READ)
715
716
def registerValue(self, registerData):
717
self.string("Registry key value data", registerData, content_type=CONTENT_TYPE.REG_READ, sort=False)
718
719
# object to manage how to print the retrieved queries output to
720
# standard output and sessions file
721
dumper = Dump()
722
723