2008-10-15 19:38:22 +04:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
"""
|
2008-10-15 19:56:32 +04:00
|
|
|
$Id$
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2012-01-11 18:59:46 +04:00
|
|
|
Copyright (c) 2006-2012 sqlmap developers (http://www.sqlmap.org/)
|
2010-10-15 03:18:29 +04:00
|
|
|
See the file 'doc/COPYING' for copying permission
|
2008-10-15 19:38:22 +04:00
|
|
|
"""
|
|
|
|
|
2010-05-24 15:00:49 +04:00
|
|
|
import codecs
|
2010-01-02 05:02:12 +03:00
|
|
|
import re
|
2010-05-24 15:00:49 +04:00
|
|
|
import os
|
2011-12-30 18:20:06 +04:00
|
|
|
import StringIO
|
2011-12-28 19:59:30 +04:00
|
|
|
import threading
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2011-02-21 01:41:42 +03:00
|
|
|
from lib.core.common import Backend
|
2008-10-15 19:38:22 +04:00
|
|
|
from lib.core.common import dataToDumpFile
|
2010-08-09 01:22:37 +04:00
|
|
|
from lib.core.common import dataToStdout
|
2010-06-02 16:31:36 +04:00
|
|
|
from lib.core.common import getUnicode
|
2011-03-24 23:04:20 +03:00
|
|
|
from lib.core.common import normalizeUnicode
|
2011-01-08 12:30:10 +03:00
|
|
|
from lib.core.common import openFile
|
2010-10-21 13:51:07 +04:00
|
|
|
from lib.core.common import restoreDumpMarkedChars
|
2011-07-03 02:48:56 +04:00
|
|
|
from lib.core.common import safeCSValue
|
2011-12-20 17:17:24 +04:00
|
|
|
from lib.core.common import unsafeSQLIdentificatorNaming
|
2008-10-15 19:38:22 +04:00
|
|
|
from lib.core.data import conf
|
2010-09-24 17:19:35 +04:00
|
|
|
from lib.core.data import kb
|
2008-10-15 19:38:22 +04:00
|
|
|
from lib.core.data import logger
|
2011-02-21 01:41:42 +03:00
|
|
|
from lib.core.enums import DBMS
|
2011-12-27 15:25:40 +04:00
|
|
|
from lib.core.exception import sqlmapValueException
|
2010-09-24 17:19:35 +04:00
|
|
|
from lib.core.replication import Replication
|
2012-03-14 17:52:23 +04:00
|
|
|
from lib.core.settings import BLANK
|
2011-12-28 19:59:30 +04:00
|
|
|
from lib.core.settings import BUFFERED_LOG_SIZE
|
2012-02-07 14:46:55 +04:00
|
|
|
from lib.core.settings import NULL
|
2011-07-24 13:19:33 +04:00
|
|
|
from lib.core.settings import TRIM_STDOUT_DUMP_SIZE
|
2011-01-30 14:36:03 +03:00
|
|
|
from lib.core.settings import UNICODE_ENCODING
|
2008-10-15 19:38:22 +04:00
|
|
|
|
|
|
|
class Dump:
|
|
|
|
"""
|
|
|
|
This class defines methods used to parse and output the results
|
|
|
|
of SQL injection actions
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self):
|
2012-02-16 18:42:28 +04:00
|
|
|
self._outputFile = None
|
|
|
|
self._outputFP = None
|
|
|
|
self._outputBP = None
|
|
|
|
self._lock = threading.Lock()
|
2010-05-28 20:43:04 +04:00
|
|
|
|
2012-02-16 18:42:28 +04:00
|
|
|
def _write(self, data, n=True, console=True):
|
2010-10-15 14:28:06 +04:00
|
|
|
text = "%s%s" % (data, "\n" if n else " ")
|
2011-07-24 13:19:33 +04:00
|
|
|
if console:
|
|
|
|
dataToStdout(text)
|
2010-10-15 14:28:06 +04:00
|
|
|
|
2011-12-28 19:59:30 +04:00
|
|
|
if kb.get("multiThreadMode"):
|
2012-02-16 18:42:28 +04:00
|
|
|
self._lock.acquire()
|
2011-12-28 19:59:30 +04:00
|
|
|
|
2012-02-16 18:42:28 +04:00
|
|
|
self._outputBP.write(text)
|
2011-12-28 19:59:30 +04:00
|
|
|
|
2012-02-16 18:42:28 +04:00
|
|
|
if self._outputBP.tell() > BUFFERED_LOG_SIZE:
|
2011-12-28 19:59:30 +04:00
|
|
|
self.flush()
|
|
|
|
|
|
|
|
if kb.get("multiThreadMode"):
|
2012-02-16 18:42:28 +04:00
|
|
|
self._lock.release()
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2011-05-11 00:44:36 +04:00
|
|
|
kb.dataOutputFlag = True
|
2010-05-28 20:43:04 +04:00
|
|
|
|
2011-12-28 19:59:30 +04:00
|
|
|
def flush(self):
|
2012-02-16 18:42:28 +04:00
|
|
|
if self._outputBP and self._outputFP and self._outputBP.tell() > 0:
|
|
|
|
_ = self._outputBP.getvalue()
|
|
|
|
self._outputBP.truncate(0)
|
|
|
|
self._outputFP.write(_)
|
2011-12-28 19:59:30 +04:00
|
|
|
|
2012-02-16 18:42:28 +04:00
|
|
|
def _formatString(self, inpStr):
|
2010-10-21 13:51:07 +04:00
|
|
|
return restoreDumpMarkedChars(getUnicode(inpStr))
|
2010-05-28 20:43:04 +04:00
|
|
|
|
2008-10-15 19:38:22 +04:00
|
|
|
def setOutputFile(self):
|
2012-02-16 18:42:28 +04:00
|
|
|
self._outputFile = "%s%slog" % (conf.outputPath, os.sep)
|
|
|
|
self._outputFP = codecs.open(self._outputFile, "ab", UNICODE_ENCODING)
|
|
|
|
self._outputBP = StringIO.StringIO()
|
2010-05-28 20:43:04 +04:00
|
|
|
|
2010-09-26 18:56:55 +04:00
|
|
|
def getOutputFile(self):
|
2012-02-27 15:15:53 +04:00
|
|
|
self.flush()
|
2012-02-16 18:42:28 +04:00
|
|
|
return self._outputFile
|
2010-09-26 18:56:55 +04:00
|
|
|
|
2009-04-22 15:48:07 +04:00
|
|
|
def string(self, header, data, sort=True):
|
2008-10-15 19:38:22 +04:00
|
|
|
if isinstance(data, (list, tuple, set)):
|
2009-04-22 15:48:07 +04:00
|
|
|
self.lister(header, data, sort)
|
2008-10-15 19:38:22 +04:00
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
if data:
|
2012-02-27 17:15:10 +04:00
|
|
|
data = self._formatString(getUnicode(data))
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2011-05-23 18:28:05 +04:00
|
|
|
if data[-1] == '\n':
|
|
|
|
data = data[:-1]
|
|
|
|
|
2008-10-15 19:38:22 +04:00
|
|
|
if "\n" in data:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("%s:\n---\n%s\n---\n" % (header, data))
|
2008-10-15 19:38:22 +04:00
|
|
|
else:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("%s: '%s'\n" % (header, data))
|
2008-10-15 19:38:22 +04:00
|
|
|
else:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("%s:\tNone\n" % header)
|
2010-09-24 17:19:35 +04:00
|
|
|
|
2009-04-22 15:48:07 +04:00
|
|
|
def lister(self, header, elements, sort=True):
|
2008-11-02 21:23:42 +03:00
|
|
|
if elements:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("%s [%d]:" % (header, len(elements)))
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-01-02 05:02:12 +03:00
|
|
|
if sort:
|
2009-04-22 15:48:07 +04:00
|
|
|
try:
|
|
|
|
elements = set(elements)
|
|
|
|
elements = list(elements)
|
2011-03-18 19:52:46 +03:00
|
|
|
elements.sort(key=lambda x: x.lower() if isinstance(x, basestring) else x)
|
2009-04-22 15:48:07 +04:00
|
|
|
except:
|
|
|
|
pass
|
2008-10-15 19:38:22 +04:00
|
|
|
|
|
|
|
for element in elements:
|
2010-05-25 14:09:35 +04:00
|
|
|
if isinstance(element, basestring):
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("[*] %s" % element)
|
2008-10-15 19:38:22 +04:00
|
|
|
elif isinstance(element, (list, tuple, set)):
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("[*] " + ", ".join(getUnicode(e) for e in element))
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2008-11-02 21:23:42 +03:00
|
|
|
if elements:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("")
|
2010-05-28 20:43:04 +04:00
|
|
|
|
2010-11-29 00:27:47 +03:00
|
|
|
def technic(self, header, data):
|
2010-05-28 20:43:04 +04:00
|
|
|
self.string(header, data)
|
|
|
|
|
|
|
|
def banner(self,data):
|
|
|
|
self.string("banner", data)
|
|
|
|
|
|
|
|
def currentUser(self,data):
|
|
|
|
self.string("current user", data)
|
|
|
|
|
|
|
|
def currentDb(self,data):
|
2011-04-30 18:54:29 +04:00
|
|
|
if Backend.isDbms(DBMS.MAXDB):
|
2011-02-21 01:41:42 +03:00
|
|
|
self.string("current database (no practical usage on %s)" % Backend.getIdentifiedDbms(), data)
|
2011-04-30 18:54:29 +04:00
|
|
|
elif Backend.isDbms(DBMS.ORACLE):
|
2011-04-01 19:56:11 +04:00
|
|
|
self.string("current schema (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data)
|
2011-02-21 01:41:42 +03:00
|
|
|
else:
|
|
|
|
self.string("current database", data)
|
2010-05-28 20:43:04 +04:00
|
|
|
|
|
|
|
def dba(self,data):
|
|
|
|
self.string("current user is DBA", data)
|
|
|
|
|
|
|
|
def users(self,users):
|
|
|
|
self.lister("database management system users", users)
|
|
|
|
|
2008-10-15 19:38:22 +04:00
|
|
|
def userSettings(self, header, userSettings, subHeader):
|
2012-02-16 18:42:28 +04:00
|
|
|
self._areAdmins = set()
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2008-11-02 21:23:42 +03:00
|
|
|
if userSettings:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("%s:" % header)
|
2008-10-15 19:38:22 +04:00
|
|
|
|
|
|
|
if isinstance(userSettings, (tuple, list, set)):
|
2012-02-16 18:42:28 +04:00
|
|
|
self._areAdmins = userSettings[1]
|
2008-10-15 19:38:22 +04:00
|
|
|
userSettings = userSettings[0]
|
|
|
|
|
|
|
|
users = userSettings.keys()
|
2011-03-18 19:52:46 +03:00
|
|
|
users.sort(key=lambda x: x.lower() if isinstance(x, basestring) else x)
|
2008-10-15 19:38:22 +04:00
|
|
|
|
|
|
|
for user in users:
|
|
|
|
settings = userSettings[user]
|
|
|
|
|
2011-02-10 17:24:04 +03:00
|
|
|
if settings is None:
|
|
|
|
stringSettings = ""
|
|
|
|
else:
|
|
|
|
stringSettings = " [%d]:" % len(settings)
|
|
|
|
|
2012-02-16 18:42:28 +04:00
|
|
|
if user in self._areAdmins:
|
|
|
|
self._write("[*] %s (administrator)%s" % (user, stringSettings))
|
2008-10-15 19:38:22 +04:00
|
|
|
else:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("[*] %s%s" % (user, stringSettings))
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2011-02-10 17:24:04 +03:00
|
|
|
if settings:
|
|
|
|
settings.sort()
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2011-02-10 17:24:04 +03:00
|
|
|
for setting in settings:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write(" %s: %s" % (subHeader, setting))
|
2008-10-15 19:38:22 +04:00
|
|
|
print
|
2010-01-09 03:05:00 +03:00
|
|
|
|
2010-05-28 20:43:04 +04:00
|
|
|
def dbs(self,dbs):
|
|
|
|
self.lister("available databases", dbs)
|
2010-01-09 03:05:00 +03:00
|
|
|
|
2008-10-15 19:38:22 +04:00
|
|
|
def dbTables(self, dbTables):
|
2010-11-11 23:37:25 +03:00
|
|
|
if isinstance(dbTables, dict) and len(dbTables) > 0:
|
2010-09-30 16:35:45 +04:00
|
|
|
maxlength = 0
|
|
|
|
|
|
|
|
for tables in dbTables.values():
|
|
|
|
for table in tables:
|
2010-10-20 02:11:17 +04:00
|
|
|
if isinstance(table, (list, tuple, set)):
|
|
|
|
table = table[0]
|
|
|
|
|
2011-03-29 10:25:17 +04:00
|
|
|
maxlength = max(maxlength, len(normalizeUnicode(table) or str(table)))
|
2010-09-30 16:35:45 +04:00
|
|
|
|
|
|
|
lines = "-" * (int(maxlength) + 2)
|
|
|
|
|
|
|
|
for db, tables in dbTables.items():
|
2010-10-20 02:11:17 +04:00
|
|
|
tables.sort()
|
2010-09-30 16:35:45 +04:00
|
|
|
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("Database: %s" % db if db else "Current database")
|
2010-09-30 16:35:45 +04:00
|
|
|
|
|
|
|
if len(tables) == 1:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("[1 table]")
|
2010-09-30 16:35:45 +04:00
|
|
|
else:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("[%d tables]" % len(tables))
|
2010-09-30 16:35:45 +04:00
|
|
|
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("+%s+" % lines)
|
2010-09-30 16:35:45 +04:00
|
|
|
|
|
|
|
for table in tables:
|
2010-10-20 02:11:17 +04:00
|
|
|
if isinstance(table, (list, tuple, set)):
|
|
|
|
table = table[0]
|
|
|
|
|
2011-03-29 10:25:17 +04:00
|
|
|
blank = " " * (maxlength - len(normalizeUnicode(table) or str(table)))
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("| %s%s |" % (table, blank))
|
2010-09-30 16:35:45 +04:00
|
|
|
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("+%s+\n" % lines)
|
2012-03-08 19:11:24 +04:00
|
|
|
elif dbTables is None or len(dbTables) == 0:
|
|
|
|
print "No tables found"
|
2010-09-30 16:35:45 +04:00
|
|
|
else:
|
|
|
|
self.string("tables", dbTables)
|
2010-12-21 13:31:56 +03:00
|
|
|
|
2008-10-15 19:38:22 +04:00
|
|
|
def dbTableColumns(self, tableColumns):
|
2011-09-19 23:08:08 +04:00
|
|
|
if isinstance(tableColumns, dict) and len(tableColumns) > 0:
|
|
|
|
for db, tables in tableColumns.items():
|
|
|
|
if not db:
|
|
|
|
db = "All"
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2011-09-19 23:08:08 +04:00
|
|
|
for table, columns in tables.items():
|
|
|
|
maxlength1 = 0
|
|
|
|
maxlength2 = 0
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2011-09-19 23:08:08 +04:00
|
|
|
colType = None
|
2011-01-20 00:46:43 +03:00
|
|
|
|
2011-09-19 23:08:08 +04:00
|
|
|
colList = columns.keys()
|
|
|
|
colList.sort(key=lambda x: x.lower() if isinstance(x, basestring) else x)
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2011-09-19 23:08:08 +04:00
|
|
|
for column in colList:
|
|
|
|
colType = columns[column]
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2011-09-19 23:08:08 +04:00
|
|
|
maxlength1 = max(maxlength1, len(column or ""))
|
|
|
|
maxlength2 = max(maxlength2, len(colType or ""))
|
2010-01-09 03:05:00 +03:00
|
|
|
|
2011-09-19 23:08:08 +04:00
|
|
|
maxlength1 = max(maxlength1, len("COLUMN"))
|
|
|
|
lines1 = "-" * (maxlength1 + 2)
|
2010-11-09 19:15:55 +03:00
|
|
|
|
2011-09-19 23:08:08 +04:00
|
|
|
if colType is not None:
|
|
|
|
maxlength2 = max(maxlength2, len("TYPE"))
|
|
|
|
lines2 = "-" * (maxlength2 + 2)
|
2010-11-09 19:15:55 +03:00
|
|
|
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("Database: %s\nTable: %s" % (db if db else "Current database", table))
|
2010-11-09 19:15:55 +03:00
|
|
|
|
2011-09-19 23:08:08 +04:00
|
|
|
if len(columns) == 1:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("[1 column]")
|
2011-09-19 23:08:08 +04:00
|
|
|
else:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("[%d columns]" % len(columns))
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2011-09-19 23:08:08 +04:00
|
|
|
if colType is not None:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("+%s+%s+" % (lines1, lines2))
|
2011-09-19 23:08:08 +04:00
|
|
|
else:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("+%s+" % lines1)
|
2010-11-09 19:15:55 +03:00
|
|
|
|
2011-09-19 23:08:08 +04:00
|
|
|
blank1 = " " * (maxlength1 - len("COLUMN"))
|
2010-11-09 19:15:55 +03:00
|
|
|
|
2011-09-19 23:08:08 +04:00
|
|
|
if colType is not None:
|
|
|
|
blank2 = " " * (maxlength2 - len("TYPE"))
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2011-09-19 23:08:08 +04:00
|
|
|
if colType is not None:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("| Column%s | Type%s |" % (blank1, blank2))
|
|
|
|
self._write("+%s+%s+" % (lines1, lines2))
|
2011-09-19 23:08:08 +04:00
|
|
|
else:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("| Column%s |" % blank1)
|
|
|
|
self._write("+%s+" % lines1)
|
2010-01-09 03:05:00 +03:00
|
|
|
|
2011-09-19 23:08:08 +04:00
|
|
|
for column in colList:
|
|
|
|
colType = columns[column]
|
|
|
|
blank1 = " " * (maxlength1 - len(column))
|
|
|
|
|
|
|
|
if colType is not None:
|
|
|
|
blank2 = " " * (maxlength2 - len(colType))
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("| %s%s | %s%s |" % (column, blank1, colType, blank2))
|
2011-09-19 23:08:08 +04:00
|
|
|
else:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("| %s%s |" % (column, blank1))
|
2010-11-09 19:15:55 +03:00
|
|
|
|
|
|
|
if colType is not None:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("+%s+%s+\n" % (lines1, lines2))
|
2010-11-09 19:15:55 +03:00
|
|
|
else:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("+%s+\n" % lines1)
|
2010-01-09 03:05:00 +03:00
|
|
|
|
2011-04-30 04:22:22 +04:00
|
|
|
def dbTablesCount(self, dbTables):
|
|
|
|
if isinstance(dbTables, dict) and len(dbTables) > 0:
|
|
|
|
maxlength1 = len("Table")
|
|
|
|
maxlength2 = len("Entries")
|
|
|
|
|
|
|
|
for ctables in dbTables.values():
|
|
|
|
for tables in ctables.values():
|
|
|
|
for table in tables:
|
|
|
|
maxlength1 = max(maxlength1, len(normalizeUnicode(table) or str(table)))
|
|
|
|
|
|
|
|
for db, counts in dbTables.items():
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("Database: %s" % db if db else "Current database")
|
2011-04-30 04:22:22 +04:00
|
|
|
|
|
|
|
lines1 = "-" * (maxlength1 + 2)
|
|
|
|
blank1 = " " * (maxlength1 - len("Table"))
|
|
|
|
lines2 = "-" * (maxlength2 + 2)
|
|
|
|
blank2 = " " * (maxlength2 - len("Entries"))
|
|
|
|
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("+%s+%s+" % (lines1, lines2))
|
|
|
|
self._write("| Table%s | Entries%s |" % (blank1, blank2))
|
|
|
|
self._write("+%s+%s+" % (lines1, lines2))
|
2011-04-30 04:22:22 +04:00
|
|
|
|
|
|
|
sortedCounts = counts.keys()
|
|
|
|
sortedCounts.sort(reverse=True)
|
|
|
|
|
|
|
|
for count in sortedCounts:
|
|
|
|
tables = counts[count]
|
|
|
|
|
|
|
|
if count is None:
|
|
|
|
count = "Unknown"
|
|
|
|
|
|
|
|
tables.sort(key=lambda x: x.lower() if isinstance(x, basestring) else x)
|
|
|
|
|
|
|
|
for table in tables:
|
|
|
|
blank1 = " " * (maxlength1 - len(normalizeUnicode(table) or str(table)))
|
|
|
|
blank2 = " " * (maxlength2 - len(str(count)))
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("| %s%s | %d%s |" % (table, blank1, count, blank2))
|
2011-04-30 04:22:22 +04:00
|
|
|
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("+%s+%s+\n" % (lines1, lines2))
|
2011-04-30 04:22:22 +04:00
|
|
|
else:
|
|
|
|
logger.error("unable to retrieve the number of entries for any table")
|
|
|
|
|
2008-10-15 19:38:22 +04:00
|
|
|
def dbTableValues(self, tableValues):
|
2010-09-24 17:34:46 +04:00
|
|
|
replication = None
|
2011-04-30 17:20:05 +04:00
|
|
|
rtable = None
|
2010-09-24 17:34:46 +04:00
|
|
|
|
2010-01-09 03:05:00 +03:00
|
|
|
if tableValues is None:
|
|
|
|
return
|
|
|
|
|
2008-10-15 19:38:22 +04:00
|
|
|
db = tableValues["__infos__"]["db"]
|
|
|
|
if not db:
|
|
|
|
db = "All"
|
|
|
|
table = tableValues["__infos__"]["table"]
|
|
|
|
|
2010-09-24 17:34:46 +04:00
|
|
|
if conf.replicate:
|
2011-12-20 17:17:24 +04:00
|
|
|
replication = Replication("%s%s%s.sqlite3" % (conf.dumpPath, os.sep, unsafeSQLIdentificatorNaming(db)))
|
2011-11-24 00:56:22 +04:00
|
|
|
else:
|
2011-12-20 17:17:24 +04:00
|
|
|
dumpDbPath = "%s%s%s" % (conf.dumpPath, os.sep, unsafeSQLIdentificatorNaming(db))
|
2008-10-15 19:38:22 +04:00
|
|
|
|
|
|
|
if not os.path.isdir(dumpDbPath):
|
|
|
|
os.makedirs(dumpDbPath, 0755)
|
|
|
|
|
2011-12-20 17:17:24 +04:00
|
|
|
dumpFileName = "%s%s%s.csv" % (dumpDbPath, os.sep, unsafeSQLIdentificatorNaming(table))
|
2011-01-08 12:30:10 +03:00
|
|
|
dumpFP = openFile(dumpFileName, "wb")
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2011-04-30 17:20:05 +04:00
|
|
|
count = int(tableValues["__infos__"]["count"])
|
|
|
|
separator = str()
|
|
|
|
field = 1
|
|
|
|
fields = len(tableValues) - 1
|
2008-10-15 19:38:22 +04:00
|
|
|
|
|
|
|
columns = tableValues.keys()
|
2011-03-18 19:52:46 +03:00
|
|
|
columns.sort(key=lambda x: x.lower() if isinstance(x, basestring) else x)
|
2008-10-15 19:38:22 +04:00
|
|
|
|
|
|
|
for column in columns:
|
|
|
|
if column != "__infos__":
|
2011-04-30 17:20:05 +04:00
|
|
|
info = tableValues[column]
|
|
|
|
lines = "-" * (int(info["length"]) + 2)
|
2008-10-15 19:38:22 +04:00
|
|
|
separator += "+%s" % lines
|
|
|
|
|
|
|
|
separator += "+"
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("Database: %s\nTable: %s" % (db if db else "Current database", table))
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-09-24 17:19:35 +04:00
|
|
|
if conf.replicate:
|
2010-09-24 18:34:05 +04:00
|
|
|
cols = []
|
2010-11-04 15:21:06 +03:00
|
|
|
|
2010-09-24 18:34:05 +04:00
|
|
|
for column in columns:
|
|
|
|
if column != "__infos__":
|
|
|
|
colType = Replication.INTEGER
|
2010-11-04 15:21:06 +03:00
|
|
|
|
2010-09-24 18:34:05 +04:00
|
|
|
for value in tableValues[column]['values']:
|
|
|
|
try:
|
2012-03-14 17:52:23 +04:00
|
|
|
if not value or value == " ": # NULL
|
2010-09-24 18:34:05 +04:00
|
|
|
continue
|
2010-11-04 15:21:06 +03:00
|
|
|
|
2012-02-22 14:45:10 +04:00
|
|
|
int(value)
|
2010-09-24 18:34:05 +04:00
|
|
|
except ValueError:
|
|
|
|
colType = None
|
|
|
|
break
|
2010-11-04 15:21:06 +03:00
|
|
|
|
2010-09-24 18:34:05 +04:00
|
|
|
if colType is None:
|
|
|
|
colType = Replication.REAL
|
2010-11-04 15:21:06 +03:00
|
|
|
|
2010-09-24 18:34:05 +04:00
|
|
|
for value in tableValues[column]['values']:
|
|
|
|
try:
|
2012-03-14 17:52:23 +04:00
|
|
|
if not value or value == " ": # NULL
|
2010-09-24 18:34:05 +04:00
|
|
|
continue
|
2010-11-04 15:21:06 +03:00
|
|
|
|
2012-02-22 14:45:10 +04:00
|
|
|
float(value)
|
2010-09-24 18:34:05 +04:00
|
|
|
except ValueError:
|
|
|
|
colType = None
|
|
|
|
break
|
2010-11-04 15:21:06 +03:00
|
|
|
|
2010-09-24 18:34:05 +04:00
|
|
|
cols.append((column, colType if colType else Replication.TEXT))
|
2010-11-04 15:21:06 +03:00
|
|
|
|
2010-09-24 18:34:05 +04:00
|
|
|
rtable = replication.createTable(table, cols)
|
2010-09-24 17:19:35 +04:00
|
|
|
|
2008-10-15 19:38:22 +04:00
|
|
|
if count == 1:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("[1 entry]")
|
2008-10-15 19:38:22 +04:00
|
|
|
else:
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("[%d entries]" % count)
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write(separator)
|
2008-10-15 19:38:22 +04:00
|
|
|
|
|
|
|
for column in columns:
|
|
|
|
if column != "__infos__":
|
2011-04-30 17:20:05 +04:00
|
|
|
info = tableValues[column]
|
2008-10-15 19:38:22 +04:00
|
|
|
maxlength = int(info["length"])
|
2011-04-30 17:20:05 +04:00
|
|
|
blank = " " * (maxlength - len(column))
|
2009-05-20 17:56:23 +04:00
|
|
|
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("| %s%s" % (column, blank), n=False)
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-09-24 17:34:46 +04:00
|
|
|
if not conf.replicate:
|
2011-11-24 00:56:22 +04:00
|
|
|
if field == fields:
|
2011-07-03 02:48:56 +04:00
|
|
|
dataToDumpFile(dumpFP, "%s" % safeCSValue(column))
|
2011-11-24 00:56:22 +04:00
|
|
|
else:
|
2011-11-30 21:39:41 +04:00
|
|
|
dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(column), conf.csvDel))
|
2008-10-15 19:38:22 +04:00
|
|
|
|
|
|
|
field += 1
|
|
|
|
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("|\n%s" % separator)
|
2009-05-20 17:56:23 +04:00
|
|
|
|
2011-11-24 00:56:22 +04:00
|
|
|
if not conf.replicate:
|
2008-10-15 19:38:22 +04:00
|
|
|
dataToDumpFile(dumpFP, "\n")
|
|
|
|
|
2011-04-14 18:34:12 +04:00
|
|
|
if conf.replicate:
|
|
|
|
rtable.beginTransaction()
|
|
|
|
|
2011-07-24 13:19:33 +04:00
|
|
|
if count > TRIM_STDOUT_DUMP_SIZE:
|
2011-12-23 00:54:20 +04:00
|
|
|
warnMsg = "console output will be trimmed to "
|
|
|
|
warnMsg += "last %d rows due to " % TRIM_STDOUT_DUMP_SIZE
|
|
|
|
warnMsg += "large table size"
|
2011-07-24 13:19:33 +04:00
|
|
|
logger.warning(warnMsg)
|
|
|
|
|
2011-10-22 02:34:27 +04:00
|
|
|
for i in xrange(count):
|
2011-07-24 13:19:33 +04:00
|
|
|
console = (i >= count - TRIM_STDOUT_DUMP_SIZE)
|
2008-10-15 19:38:22 +04:00
|
|
|
field = 1
|
2010-09-24 17:19:35 +04:00
|
|
|
values = []
|
2008-10-15 19:38:22 +04:00
|
|
|
|
|
|
|
for column in columns:
|
|
|
|
if column != "__infos__":
|
|
|
|
info = tableValues[column]
|
|
|
|
|
2011-01-04 02:36:35 +03:00
|
|
|
if len(info["values"]) <= i:
|
|
|
|
continue
|
|
|
|
|
2011-05-12 16:00:17 +04:00
|
|
|
if info["values"][i] is None:
|
|
|
|
value = u''
|
|
|
|
else:
|
|
|
|
value = getUnicode(info["values"][i])
|
2012-03-14 17:52:23 +04:00
|
|
|
value = {" ": NULL, "": BLANK}.get(value, value)
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-09-24 17:19:35 +04:00
|
|
|
values.append(value)
|
2008-10-15 19:38:22 +04:00
|
|
|
maxlength = int(info["length"])
|
2010-05-24 15:00:49 +04:00
|
|
|
blank = " " * (maxlength - len(value))
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("| %s%s" % (value, blank), n=False, console=console)
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-09-24 17:34:46 +04:00
|
|
|
if not conf.replicate:
|
2011-11-24 00:56:22 +04:00
|
|
|
if field == fields:
|
2011-07-03 02:48:56 +04:00
|
|
|
dataToDumpFile(dumpFP, "%s" % safeCSValue(value))
|
2011-11-24 00:56:22 +04:00
|
|
|
else:
|
2011-11-30 21:39:41 +04:00
|
|
|
dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(value), conf.csvDel))
|
2008-10-15 19:38:22 +04:00
|
|
|
|
|
|
|
field += 1
|
|
|
|
|
2010-09-24 17:19:35 +04:00
|
|
|
if conf.replicate:
|
2011-12-27 15:25:40 +04:00
|
|
|
try:
|
|
|
|
rtable.insert(values)
|
|
|
|
except sqlmapValueException:
|
|
|
|
pass
|
2010-09-24 17:19:35 +04:00
|
|
|
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("|", console=console)
|
2009-05-20 17:56:23 +04:00
|
|
|
|
2011-11-24 00:56:22 +04:00
|
|
|
if not conf.replicate:
|
2008-10-15 19:38:22 +04:00
|
|
|
dataToDumpFile(dumpFP, "\n")
|
|
|
|
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write("%s\n" % separator)
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-09-24 17:34:46 +04:00
|
|
|
if conf.replicate:
|
2011-04-14 18:34:12 +04:00
|
|
|
rtable.endTransaction()
|
2010-09-24 17:34:46 +04:00
|
|
|
logger.info("Table '%s.%s' dumped to sqlite3 file '%s'" % (db, table, replication.dbpath))
|
2011-04-14 18:34:12 +04:00
|
|
|
|
2011-11-24 00:56:22 +04:00
|
|
|
else:
|
2008-10-15 19:38:22 +04:00
|
|
|
dataToDumpFile(dumpFP, "\n")
|
|
|
|
dumpFP.close()
|
|
|
|
logger.info("Table '%s.%s' dumped to CSV file '%s'" % (db, table, dumpFileName))
|
|
|
|
|
2011-06-24 13:29:11 +04:00
|
|
|
def dbColumns(self, dbColumnsDict, colConsider, dbs):
|
|
|
|
for column in dbColumnsDict.keys():
|
2010-05-28 20:43:04 +04:00
|
|
|
if colConsider == "1":
|
|
|
|
colConsiderStr = "s like '" + column + "' were"
|
|
|
|
else:
|
|
|
|
colConsiderStr = " '%s' was" % column
|
|
|
|
|
2011-04-30 17:20:05 +04:00
|
|
|
msg = "Column%s found in the " % colConsiderStr
|
2010-05-28 20:43:04 +04:00
|
|
|
msg += "following databases:"
|
2012-02-16 18:42:28 +04:00
|
|
|
self._write(msg)
|
2010-05-28 20:43:04 +04:00
|
|
|
|
2012-02-16 18:42:28 +04:00
|
|
|
_ = {}
|
2010-05-28 20:43:04 +04:00
|
|
|
|
|
|
|
for db, tblData in dbs.items():
|
|
|
|
for tbl, colData in tblData.items():
|
|
|
|
for col, dataType in colData.items():
|
|
|
|
if column.lower() in col.lower():
|
2012-02-16 18:42:28 +04:00
|
|
|
if db in _:
|
|
|
|
if tbl in _[db]:
|
|
|
|
_[db][tbl][col] = dataType
|
2010-05-28 20:43:04 +04:00
|
|
|
else:
|
2012-02-16 18:42:28 +04:00
|
|
|
_[db][tbl] = { col: dataType }
|
2010-05-28 20:43:04 +04:00
|
|
|
else:
|
2012-02-16 18:42:28 +04:00
|
|
|
_[db] = {}
|
|
|
|
_[db][tbl] = { col: dataType }
|
2010-05-28 20:43:04 +04:00
|
|
|
|
|
|
|
continue
|
|
|
|
|
2012-02-16 18:42:28 +04:00
|
|
|
self.dbTableColumns(_)
|
2010-05-28 20:43:04 +04:00
|
|
|
|
|
|
|
def query(self, query, queryRes):
|
2010-10-19 12:55:14 +04:00
|
|
|
self.string(query, queryRes)
|
2010-05-28 20:43:04 +04:00
|
|
|
|
|
|
|
def rFile(self,filePath,fileData):
|
2012-02-22 14:45:10 +04:00
|
|
|
self.string("%s file saved to" % filePath,fileData,sort=False)
|
2010-05-28 20:43:04 +04:00
|
|
|
|
|
|
|
def registerValue(self,registerData):
|
|
|
|
self.string("Registry key value data", registerData,sort=False)
|
|
|
|
|
2008-10-15 19:38:22 +04:00
|
|
|
# object to manage how to print the retrieved queries output to
|
|
|
|
# standard output and sessions file
|
|
|
|
dumper = Dump()
|